9
votes

I need to change Logon user for a Windows service programmatically. And I am using the following code to do that:

string objPath = string.Format("Win32_Service.Name='{0}'", ServiceName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
object[] wmiParams = new object[11];

if (PredefinedAccount)
    {
        wmiParams[6] = "LocalSystem";
            wmiParams[7] = "";
    }
    else
    {
        wmiParams[6] = ServiceUsername; // provided by user
            wmiParams[7] = ServicePassword; // provided by user
    }

    object invokeResult = service.InvokeMethod("Change", wmiParams);

// handle invokeResult - no error up to this point
}

This code works in 90% of situations, but in some situations service cannot be started due to logon failure. There is usually no error on InvokeMetod but when we try to start the service we get the following error:

System.InvalidOperationException: Cannot start service X on computer '.'. --> System.ComponentModel.Win32Exception: The service did not start due to a logon failure.

The workaround solution is simple, we just need to enter the same credentials via Windows interface and problem is solved.

So my question is, has anybody experienced the similar problem with ManagementObject because it seems that in some situation it does not relate Username and password to windows service?

2
I wonder if it is due to your using statement. What I mean is the ManagementObject getting destroyed before it is allowed to complete? I'm not overly familiar with WMI, so I'm not sure. - Hans Van Slooten
Since the username and password is user entered, I would look there for problems as well. Make sure they are valid names. "DOMAIN\username" is good in any system, but 'username@DOMAIN' doesn't work in Windows 2000 and earlier. - Hans Van Slooten
We have the same problem and I'm pretty sure the service was installed with a C#, .net 1.1 installation program. I start the service from the command line ('net start') and get logon failure. Strangely this happens with 2 out of 7 services that are installed on the machine (likely using the same installation code). I haven't got around to diagnosing it yet but the machine is windows 2003 server with latest service packs. The services are c# .net 2.0 code. Typing the password manually fixes it until reboot. - LegendLength
@HVS: Yes, we are forcing them to enter username as 'DOMAIN\username'. - Anne
I think HVS's first comment has some merit. It is possible that the WMI object is being disposed of before the logon is complete, especially if the logon consults a domain or directory controlled on another machine. Credentials might be cached after the user logs on interactively, which might explain why it then works for you. Try looping over something that tests the logon, which should keep the WMI object alive long enough to logon. Or remove the using statement. - flipdoubt

2 Answers

9
votes

It's because the account has no "Log On as service" privilege. You need to use LsaAddAccountRights to add such privilege to the account.

View this article please:

How To Manage User Privileges Programmatically in Windows NT

0
votes

Do you notice any patterns amongst those failures? Same machine? Same OS? Same user? Does the user have "logon as service" or "logon interactively" rights? Personally, I am not familiar with this method of specifying the user for a service. I would have thought you would have to restart the service, but I guess not if it works 90% of the time.