我想创build一个程序Foo.exe
并logging到foo.log
。 该程序已安装(NSIS安装程序)到C:\Program Files (x86)\Foo\
。 在安装期间,NSIS在Windows启动时添加了一个快捷方式( CreateShortCut "$SMSTARTUP\Foo.lnk" "$INSTDIR\Foo.exe"
)来启动Foo.exe
。
C:\Program Files (x86)\Foo\foo.log
。 解决方法是将可编辑文件存储在另一个目录中,例如$APPDATA
。 FooNew.exe
。 该文件没有任何权限(显式不是执行标志)。 FooCopy.exe
FooCopy.exe
打开FooNew.exe
并将其内容写入Foo.exe
。 现在, Foo.exe
已更新并具有执行权限。 FooCopy.exe
将被删除。 所以我没有testet更新,但很可能它不会工作。 我假设Foo.exe
无法在C:\Program Files (x86)\Foo\
创build文件,因此更新在第1点失败。
一个想法是将Foo.exe
不保存在C:\Program Files (x86)\
而是保存在$APPDATA
。 所以这个程序有所需要的权利。 问题是启动该程序:它被编译为32位。 有可能有一个“启动程序” C:\Program Files (x86)\Foo\launcher.exe
启动$APPDATA
的真实应用程序?
这是困惑,不是吗? 我怎么能改变自动更新程序,以便UAC不会踢我?
作为一个例子,我看到firefox.exe
。 它如何更新,从而直接写入C:\Program Files (x86)\...
通常没有人可以写入该目录没有提示用户。
克里斯
Firefox使用NT服务。 服务通常以SYSTEM的身份运行,因此它可以在任何地方复制文件,Mozilla配置其服务,以便可以由普通用户启动 。
在程序文件中有一个启动程序和appdata中的主要应用程序没有任何意义,您可能还需要按照每个用户的安装(如Chrome等)。
我假设你的应用程序不是一个网页浏览器,所以保持最新可能不是那么重要。 我建议你的更新只是检查更新,如果有更新,你可以重新生成自己(或主更新?)作为管理员使用UAC,然后进行更新。
您的“更新”过程需要使用管理权限运行。
如果启用了UAC,则可以让Windows通过将runas
动词传递给ShellExecute
来启动升级器:
Boolean RunAsAdmin(HWND hWnd, String filename, String, parameters) { /* See Step 3: Redesign for UAC Compatibility (UAC) http://msdn.microsoft.com/en-us/library/bb756922.aspx */ ShellExecuteInfo sei; ZeroMemory(ref sei, sizeoOf(sei)); sei.cbSize = sizeof(TShellExecuteInfo); sei.Wnd = hwnd; sei.fMask = SEE_MASK_FLAG_DDEWAIT || SEE_MASK_FLAG_NO_UI; sei.lpVerb = "runas"; sei.lpFile = Filename; if (parameters <> '') sei.lpParameters = parameters; sei.nShow = SW_SHOWNORMAL; return ShellExecuteEx(ref sei); }
如果UAC未启用(例如用户在Windows XP上运行),则用户将别无选择,只能以具有管理权限的用户注销和登录。
注意 :任何代码发布到公共领域。 不需要归属