我想创建一个程序Foo.exe
,错误登录到foo.log
。该程序已安装(NSIS安装程序)到C:\Program Files (x86)\Foo\
。在安装过程中,NSIS添加了一个快捷方式(CreateShortCut "$SMSTARTUP\Foo.lnk" "$INSTDIR\Foo.exe"
),以便在Windows启动时启动Foo.exe
。
C:\Program Files (x86)\Foo\foo.log
。解决方法是将可编辑文件存储在另一个目录中,例如在$APPDATA
。FooNew.exe
。此文件没有任何权限(显式不是execute-flag)。FooCopy.exe
FooCopy.exe
会打开FooNew.exe
并将其内容写入Foo.exe
。现在,Foo.exe
已更新并具有执行权限。FooCopy.exe
将被删除。所以我没有测试更新,但很可能它不会工作。我假设Foo.exe
无法在C:\Program Files (x86)\Foo\
中创建文件,因此更新在第1点失败。
一个想法是将Foo.exe
保存在C:\Program Files (x86)\
但不在$APPDATA
中。所以该计划拥有所有必要的权利。问题是启动该程序:它是为32位编译的。是否有可能拥有一个发射器" C:\Program Files (x86)\Foo\launcher.exe
启动$APPDATA
中的实际应用程序?
这很困惑,不是吗?我怎么能改变自动更新程序,以便UAC不会踢我?
作为一个例子,我看到firefox.exe
。因此,当正常没有人可以在不提示用户的情况下写入该目录时,如何更新,直接写入C:\Program Files (x86)\...
。
克里斯
答案 0 :(得分:2)
Firefox使用NT服务。服务通常作为SYSTEM运行,因此它可以在任何地方复制文件,Mozilla可以配置他们的服务,以便普通用户可以启动。
在程序文件和appdata中的主应用程序中使用启动程序是没有意义的,在这种情况下你也可以按用户安装(如Chrome等)。
我认为您的应用程序不是Web浏览器,因此保持最新状态可能并不重要。我建议您的更新程序只检查更新,如果有更新,您可以使用UAC以管理员身份再次生成自己(或主更新程序?),然后进行更新。
答案 1 :(得分:0)
您的“更新”流程需要使用管理权限运行。
如果启用了UAC,则可以通过将 runas
动词传递给ShellExecute
来要求Windows启动更新程序:
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上运行),则用户将别无选择,只能以 具有管理权限的用户身份注销和登录。
注意:任何已发布到公共领域的代码。无需归属。