
Privilege not held on InvokeMethod
The native (COM) method "Win32Shutdown" is running on the process unmanaged MTA thread (like all other native WMI COM methods),
however, as your code is run on a UI (STA) thread, the SE_SHUTDOWN privilege set on the UI thread and not propagated to the MTA
thread (which is normal), which results in a security exception when the Win32Shutdown call is made.
To solve this problem, you must make sure to run your "reboot" code on a MTA thread, f.i using an asynch. delegate.
// Show dialog box
......
// If OK to reboot ....
public delegate void RebootProc();
// Call reboot from an MTA worker thread
RebootProc pfn = new RebootProc(Reboot);
IAsyncResult ar = pfn.BeginInvoke( null, null);
ar.AsyncWaitHandle.WaitOne(10000, false);
}
static void Reboot( )
{
// Your reboot code here....
// It is critical to call EnablePrivileges on this thread (MTA)
....
ms.Options.EnablePrivileges = true;
...
}
Willy.
Quote:
> I've modified the below bit of code from an earlier post about rebooting a
> machine. It works great except for one thing. If I display a MessageBox
> before calling InvokeMethod, I get a security exception. If I don't display
> the MessageBox everything works fine and the machine reboots. Any ideas on
> why the MessageBox changes the security permissions? I want to display the
> MessageBox asking the user if they are sure they want to restart.
> Thanks.
> -Mikel
> ConnectionOptions co = new ConnectionOptions();
> System.Management.ManagementScope ms = new
> System.Management.ManagementScope("\\root\\cimv2", co);
> //Query remote computer across the connection
> System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT
> * FROM Win32_OperatingSystem");
> //elevate the privilages so the program can perform the reboot
> ms.Options.EnablePrivileges = true;
> ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms,oq);
> ManagementObjectCollection queryCollection1 = query1.Get();
> foreach( ManagementObject mo in queryCollection1 )
> {
> string[] ss={"2","0"};
> mo.InvokeMethod("Win32Shutdown",ss);
> }