Search code examples
.netmultithreadinginstrumentsprivilege

privilege across threads with management objects in .net


public class ManageComp
{
    ManagementObject _moOpSystem;

    public ManageComp()
    {
        ManagementScope scope = new ManagementScope(
            "\\\\.\\root\\cimv2",
            new ConnectionOptions() { EnablePrivileges = true });
        scope.Connect();
        ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
        ManagementObjectSearcher searcher =
            new ManagementObjectSearcher(scope, query);
        foreach(ManagementObject m in searcher.Get())
        {
            _moOpSystem = m;
        }
    }

    public void RebootComputer()
    {
        _moOpSystem.InvokeMethod("Reboot", null);
    }
}

static class Program
{

    public static ManageComp ManComp = new ManageComp();


    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        new Thread(new ThreadStart(delegate()
            {
                Application.Run(new FormMain()
                {
                    Text = "Another Thread"
                });
            })).Start();


        Application.Run(new FormMain()
            {
                Text = "Main Thread"
            });
    }
}

when i call RebootComputer from the form whose title is "Main Thread" the computer successfully reboots, but calling the same method from the form whose title is "Another Thread" causes an exception that saying "Privilege not held"

here is the button click code

private void button1_Click(object sender, EventArgs e)
{
    Program.ManComp.RebootComputer();
}

how can i overcome this strange problem? why that is happening ?


Solution

  • i have solved the problem with setting the apartment state of the thread. but i don't really know how apartment state is related to that strange privilege problem.

    here is the new creation style of the thread.

            Thread th = new Thread(new ThreadStart(delegate()
                {
                    Application.Run(new FormMain()
                    {
                        Text = "Another Thread"
                    });
                }));
            th.SetApartmentState(ApartmentState.STA);
            th.Start();
    

    i'm still trying to dig up what is the real cause behind the problem, if anyone has a guess, please save me from this search