Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the a windows service log on credentials?

How do I programmatically set the "Log On" credentials for an arbitrary Windows service using c# (wmi/interop is fine)?

Note, my program is running as an administrator and I need the change to persist (for all subsequent service restarts)

Ideally the method has the following sig:

void SetWindowsServiceCreds(string serviceName, string username, string password) 
{
   // TODO write me
}
like image 343
Sam Saffron Avatar asked Dec 19 '10 04:12

Sam Saffron


People also ask

How to log on as a service in Windows 10?

In the right pane, right-click ‘Log on as a service’ and select properties. Click on the ‘Add User or Group…’ button to add the new user. In the ‘Select Users or Groups’ dialogue, find the user you wish to enter and click ‘OK’ Click ‘OK’ in the ‘Log on as a service Properties’ to save changes. Then try again with the added user.

How do I assign a user to log on as a service?

Expand Local Policy and click User Rights Assignment. In the right pane, right-click Log on as a service and select Properties. Click Add User or Group option to add the new user. In the Select Users or Groups dialogue, find the user you wish to add and click OK. Click OK in the Log on as a service Properties to save the changes.

How do I set the ‘logon as a service’ permission?

Perform the following to edit the Local Security Policy of the computer you want to define the ‘logon as a service’ permission: Logon to the computer with administrative privileges. In the right pane, right-click ‘Log on as a service’ and select properties.

How do I add a new user to the login screen?

Logon to the computer with administrative privileges. In the right pane, right-click ‘Log on as a service’ and select properties. Click on the ‘Add User or Group…’ button to add the new user. In the ‘Select Users or Groups’ dialogue, find the user you wish to enter and click ‘OK’ Click ‘OK’ in the ‘Log on as a service Properties’ to save changes.


2 Answers

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ChangeServiceConfig(IntPtr hService, UInt32 nServiceType, UInt32 nStartType, UInt32 nErrorControl, String lpBinaryPathName, String lpLoadOrderGroup, IntPtr lpdwTagId, String lpDependencies, String lpServiceStartName, String lpPassword, String lpDisplayName);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);

[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr OpenSCManager(
     string machineName,
     string databaseName,
     uint dwAccess);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseServiceHandle(IntPtr hSCObject);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean QueryServiceConfig(IntPtr hService, IntPtr intPtrQueryConfig, UInt32 cbBufSize, out UInt32 pcbBytesNeeded);

[StructLayout(LayoutKind.Sequential)]
public class QUERY_SERVICE_CONFIG
{
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwServiceType;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwStartType;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwErrorControl;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpBinaryPathName;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpLoadOrderGroup;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwTagID;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpDependencies;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpServiceStartName;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpDisplayName;
};

private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const uint SERVICE_QUERY_CONFIG = 0x00001;
private const uint SERVICE_CHANGE_CONFIG = 0x00002;
private const uint SERVICE_NO_CHANGE = 0xffffffff;
private const int ERROR_INSUFFICIENT_BUFFER = 122;

public static void SetWindowsServiceCreds(string serviceName, string username, string password)
{
    IntPtr hManager = IntPtr.Zero;
    IntPtr hService = IntPtr.Zero;
    try
    {
        hManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
        if (hManager == IntPtr.Zero)
        {
            ThrowWin32Exception();
        }
        hService = OpenService(hManager, serviceName, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
        if (hService == IntPtr.Zero)
        {
            ThrowWin32Exception();
        }

        if (!ChangeServiceConfig(hService, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, username, password, null))
        {
            ThrowWin32Exception();
        }
    }
    finally
    {
        if (hService != IntPtr.Zero) CloseServiceHandle(hService);
        if (hManager != IntPtr.Zero) CloseServiceHandle(hManager);
    }
}

private static void ThrowWin32Exception()
{
    int error = Marshal.GetLastWin32Error();
    Win32Exception e = new Win32Exception(error);
    throw e;            
}
like image 151
Harvey Kwok Avatar answered Sep 28 '22 02:09

Harvey Kwok


This works as well:

      void SetWindowsServiceCreds(string serviceName, string username, string password)
        {
            string objPath = string.Format("Win32_Service.Name='{0}'", serviceName);
            using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
            {
                object[] wmiParams = new object[10];

                wmiParams[6] = username;
                wmiParams[7] = password;
                service.InvokeMethod("Change", wmiParams);
            }

        }
like image 28
Sam Saffron Avatar answered Sep 28 '22 01:09

Sam Saffron