Ok so since in xp most people are logged as admins - it's easy for a programmer to make a program work with the registry. What I am trying to do is this:
The software is started and it's added as a startup process in the registry- however this should be done only when the application is closing - not before.
However this doesn't work in xp when the user is limited and same thing in vista,7,2008.
What are the workarounds? I was thinking to make the program create a scheduled task or being attached to a process with higher privilleges? Any working way? I am taggin this as .net since my software is .net related - actually same thing happens and in c++ - but i secretly hope that net offers easier methods to work it out.
10x in advance!
Um, this isn't a limitation of Windows 7; it's actually by-design. See my answer here for details.
What you need is called process elevation. It's the standard way of dealing with this, a mechanism built into UAC to allow users to authenticate themselves as Administrators and temporarily gain all of the privileges and responsibilities that come with this title. Windows itself uses this all over the place:
There's a fantastic how-to article available here: Shield icons, UAC, and process elevation in .NET.
But just to summarize in case of link rot, here are the steps:
Determine if the user has the appropriate permissions already. The simplest way is calling the IsUserAnAdmin
API function.
Notify the user that elevation is required using a "shield" icon. In WinForms, you need to set the button's FlatStyle
property to "System", and use P/Invoke to display the shield. Sample code:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg,
IntPtr wParam, IntPtr lParam);
public const int BCM_SETSHIELD = 0x0000160C;
public static void SetButtonShield(Button btn, bool showShield)
{
// Verify that we're running on Vista or later
if ((Environment.OSVersion.Platform == PlatformID.Win32NT) &&
(Environment.OSVersion.Version.Major >= 6))
{
SendMessage(btn.Handle, BCM_SETSHIELD, IntPtr.Zero,
showShield ? new IntPtr(1) : IntPtr.Zero);
}
}
Re-launch the process with administrator privileges. This involves showing the elevation dialog to allow the user to elevate the program. Sample code:
ProcessStartInfo psi = new ProcessStartInfo
{
Arguments = "-justelevated",
ErrorDialog = true,
// Handle is the handle for your form
ErrorDialogParentHandle = Handle,
FileName = Application.ExecutablePath,
Verb = "runas"
};
try
{
Process.Start(psi);
Close();
}
catch (Exception ex)
{
// the process couldn't be started. This happens for 1 of 3 reasons:
// 1. The user cancelled the UAC box
// 2. The limited user tried to elevate to an Admin that has a blank password
// 3. The limited user tries to elevate as a Guest account
MessageBox.Show(ex.Message);
}
[Optional] Code sign your application to replace the hostile-looking yellow UAC elevation box with a more pleasing gray or blue one.
It should be per user anyway, and then you won't have permission problems. HKCU\Software\Microsoft\Windows\CurrentVersion\Run
the whole purpose of limited users is to prevent this.