Reputation: 307
I want to create a program Foo.exe
with error logging into foo.log
. That program is installed (NSIS Installer) into C:\Program Files (x86)\Foo\
. During installation NSIS added a shortcut (CreateShortCut "$SMSTARTUP\Foo.lnk" "$INSTDIR\Foo.exe"
) to start Foo.exe
when windows starts.
C:\Program Files (x86)\Foo\foo.log
. Workaround for that is to store editable files in another directory e.g. in $APPDATA
.FooNew.exe
. This file does not have any permissions (explicitly not the execute-flag).FooCopy.exe
FooCopy.exe
opens FooNew.exe
and writes it content into Foo.exe
. Now, Foo.exe
is updated and has the execute-permission.FooCopy.exe
will be removed.So I have not testet the updating but most likely it wont work. I assume that Foo.exe
can not create files in C:\Program Files (x86)\Foo\
so the updating fails at point 1.
An idea is to save Foo.exe
not in C:\Program Files (x86)\
but in $APPDATA
. So the program has all needed rights. The question is starting that program: It is compiled for 32-bit. Is it possible to have a "launcher" C:\Program Files (x86)\Foo\launcher.exe
which starts the real application in $APPDATA
?
That's confused, isn't it? How could I change the auto-update procedure so that UAC will not kick me?
As an example I see firefox.exe
. How does it updating, thus, writing directly into C:\Program Files (x86)\...
when normally no one could write into that directory without prompting the user.
Chris
Upvotes: 3
Views: 224
Reputation: 256651
Your "updating" process needs to be run with administrative permissions.
If UAC is enabled, then you can ask Windows to launch your updater elevated by passing the runas
verb to 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);
}
If UAC is not enabled (e.g. the user is running on Windows XP), the user will have no choice but to logoff and login as a user who does have administrative privileges.
Note: Any code released into public domain. No attribution required.
Upvotes: 0
Reputation: 101606
Firefox uses a NT service. Services normally run as SYSTEM so it can copy files anywhere and Mozilla configures their service so it can be started by a normal user.
It does not make sense to have a launcher in program files and the main app in appdata, you might as well do a per user install in that case (Like Chrome etc).
I assume your application is not a web-browser so keeping it up to date is probably not that critical. I would suggest that your updater just checks for updates and if there is a update you can spawn yourself again (or the main updater?) as Administrator using UAC and then do the update.
Upvotes: 2