下面是回答狐狸天堂中的一位网友提问时写的代码,他的情况是:正常情况下,所有机器都是以受限用户登录的,而他的程序需要自动注册一些 ActiveX 控件,由于机器数量比较多,虽然可以手工切换到管理员来完成安装,但以后增加功能时加入新的控件或重装系统时都需要手工切换,所以他希望他的程序可以在受限用户的权限下也能正常运行;也就是说,程序启动时,可以从一个加密文件中取出管理员口令,临时以管理员身份调用 regsvr32 自动注册这些控件。虽然你也可以直接用 run 命令调用操作系统提供的 runas 来实现同样的功能,但那样做你无法知道 runas 运行是否成功。
这里我们不管他准备采用什么策略来获取管理员口令,只用实现在知道口令后切换用户来完成注册的函数:
以上的代码完成了:切换用户,以切换后的用户权限创建一个新进程,在新进程中加载并运行指定的命令或应用程序,如果切换或加载过程中发生错误,返回 Windows 的错误代码;否则,等待命令或应用程序执行完毕,返回它的退出码。
按照通常的规则,一个命令或应用程序在它正常结束时的退出码为 0,发生错误时返回非 0 值,但这个退出码的含义并无强制性规定,对于 regsvr32 这个特定的程序,它使用了与 api 错误代码一致的规则,所以可以在调用 CreateProcessWithLogonW 失败时直接返回 GetLastError() 的值,这样调用者可以在执行 RunAs 后用一致的代码来处理错误。但是,这个 RunAs 并非只为调用 regsvr32 编写,所以情况不会总是这样,很多应用程序没有遵循 Windows 错误代码规则来指示结束后的退出码;退出码的具体含义需要参照该程序的文档(如果有提供的话)。
写完这些后,想到可能还需要一个功能,就是指定是否隐藏运行时的窗口,对于 Windows 程序意义不大,但如果要执行的是一个 DOS 16位命令行程序,可能就会需要了,很多人都讨厌那个黑色的 DOS 窗口。不过这个也不难,RunAs 最后增加一个参数用于指定是否隐藏窗口,构造 lcSI 结构参数时为 dwFlags 成员指定 STARTF_USESHOWWINDOW 标志并设置合适的 wShowWindow 成员即可。
-------------------------------------------------------------------------------------
回复提问用截图