我的应用程序有一个内置的自我更新系统,通过另一个名为" 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注册表存储用户首选项的选项吗?
谢谢你们。
答案 0 :(得分:3)
提升"去除"子进程是通过资源管理器启动它。这通常通常与普通的Win用户一起工作。但是如果资源管理器本身正在升级,那么您尝试启动的应用程序也将如此。 Explorer可能正在升级,因为:
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()
此图显示结果:
表单顶部的标签表示 应用程序是否正在升级,每个应用程序实例都是由之前的应用程序启动的。
第二个窗口正在升高。当它启动下一个实例时, As Admin 的复选框未被检查;因此,第三个实例是通过资源管理器启动的,不是正在运行。同样#4从#5开始。