What you need to do is move the license information to a location that all users can write to:
- user's own environment variable
- %CSIDL_COMMON_APPDATA% (e.g.
C:\ProgramData
, which all users can write to)
- HKEY_CURRENT_USER
The ideal solution involves writing to a common machine-wide location:
- %CSIDL_COMMON_APPDATA% (e.g.
C:\ProgramData
)
- HKEY_LOCAL_MACHINE/Software/Contoso/License
- C:\Program Files\Contoso\License\license.txt
Legacy software can't be changed
But assuming there are many existing unchangeable applications that cannot be altered to look anywhere else but an environment variable for license information you can (after you smack that guy who designed that):
- write the license information to the user's own environment variable
Your switching tool will call:
SetEnvironmentVariable("ContosoLicenseInfo", "V2h5IGFyZSB5b3UgZGVjb2RpbmcgdGhpbmdzIHRoYXQgZG9uJ3QgYmVsb25nIHRvIHlvdT8=");
What would you have done under Windows XP
All this hand-wringing about UAC. You have to ask yourself:
What would I have done under Windows XP?
Without UAC, and the user running as a standard user, what will your license switching tool have done?
- would have it crashed horribly on startup?
- would it have crashed as soon as the user tried to use it?
- would it have failed in a polite way?
- would it show a message on startup saying: "Sorry, no."?
What would you have done under Windows 7?
Even better, you have to ask what you would have done for a user running under Windows 7? A standard user logs in, and you have a program in their startup group that claims to require administrative privileges.
The user needs to go get an administrator during login to run your tool? That's not going to fly.
- If you're dead set against using a per-user location.
- If you're dead set against using a common location that all users can write to
Then change your tool to run without needing user privileges.
Only when the user goes to do something do you need admin privileges.
Check if the user is an admin:
Boolean IsUserAnAdmin()
{
PSID administratorsGroup;
administratorsGroup = AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
Boolean result = CheckTokenMembership(0, administratorsGroup);
FreeSid(administratorsGroup);
}
If they are an admin, you can perform the action as in.
If the user is not an admin, then you put the UAC shield on the
Apply button.
You then re-launch your tool as an admin:
ShellExecute("runas", "C:\Program Files\Contoso\LicenseSwitcher.exe", ...); //the "runas" verb triggers elevation
But what would you do under Windows 7
None of the UAC stuff works if UAC is disabled. In that case: you are a standard user, and that's it.
In that case, it really is best to convert to:
- machine wide location for the default license
- per-user location if you want to choose your own