从提升/作为管理员流程

时间:2015-05-09 23:13:40

标签: vb.net uac privileges runas my.settings

我的应用程序有一个内置的自我更新系统,通过另一个名为" updater.exe"它与要更新的主应用程序位于同一文件夹中。它下载最新版本,终止旧版本(如果它正在运行),然后覆盖它。

问题是,为此,必须使用管理员权限运行updater.exe才能访问C:\Program Files\MyApp

到目前为止,主应用程序运行具有管理员权限的updater.exe(使用UAC),但随后出现问题:

更新完成后,我希望新安装的版本自动启动。你猜怎么着?当然主应用程序也运行Admin权限。场景很简单:

Main app[running as user] --> Updater App[run as admin] --> Main app[ADMIN again]

仅仅因为我的应用程序使用My.Settings对象,它在以管理员身份运行时会丢失所有存储的设置,因为它通常始于普通用户并且您可能知道,My.Settings是{{1}对象。

我该如何解决这个问题?我已经四处搜索但找不到与&#34相关的任何内容;以普通用户身份运行"但总是作为管理员运行,这很容易。

嗯,老实说,另一方面,我不认为这样的事情是可能的,因为更新程序应用程序无法知道哪个特定用户已启动它。或者可以吗?我有什么东西在这里失踪吗?

如果我是对的,这是唯一不使用My.Settings但Windows注册表存储用户首选项的选项吗?

谢谢你们。

1 个答案:

答案 0 :(得分:3)

提升"去除"子进程是通过资源管理器启动它。这通常通常与普通的Win用户一起工作。但是如果资源管理器本身正在升级,那么您尝试启动的应用程序也将如此。 Explorer可能正在升级,因为:

  • 活跃用户是Admin(不只是具有admin privs的用户)
  • Explorer.exe是(重新)从命令窗口启动的......你得到它,正在升级

......可能还有其他人。

最好将此视为使用默认权限启动应用。如果运行提升的资源管理器将启动升级的新实例,但原始的第一个主应用程序实例也将升级。

使用复选框测试代码以启动相同的应用程序以选择是否提升:

Dim proc = New Process
proc.StartInfo.UseShellExecute = True
proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal
proc.StartInfo.WorkingDirectory = mypath

If chkAdmin.Checked Then                    ' run this app as admin
    proc.StartInfo.FileName = myApp
    proc.StartInfo.WorkingDirectory = mypath
    proc.StartInfo.Verb = "runas"           ' run "me" as admin
    proc.StartInfo.Arguments = ""
Else                                        ' run explorer w/app as arg
    ' de-elevate new app instance to run de-elevated
    proc.StartInfo.FileName = Path.Combine(windir, "explorer.exe")  
    proc.StartInfo.Verb = ""                ' important!
    proc.StartInfo.Arguments = myApp        ' send the child app name as arg
End If

proc.Start()

此图显示结果:

enter image description here

表单顶部的标签表示 应用程序是否正在升级,每个应用程序实例都是由之前的应用程序启动的。

第二个窗口正在升高。当它启动下一个实例时, As Admin 的复选框未被检查;因此,第三个实例是通过资源管理器启动的,不是正在运行。同样#4从#5开始。