1. 程式人生 > WINDOWS開發 >C# 改變Windows中服務的登入身份 (賬戶名和密碼)

C# 改變Windows中服務的登入身份 (賬戶名和密碼)

在 C# 中,我們可以使用 WMI 類中的 Win32_Service 或者 Win32 API 中的函式 ChangeServiceConfig 來修改本地或遠端計算機 Windows 服務登入身份 (賬戶) 的使用者名稱和密碼。

1、使用 Win32 API 修改服務登入身份資訊:

使用 Win32 API 中的函式ChangeServiceConfig更改的是服務控制管理器資料庫中指定服務的配置資訊。

private const int SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const uint SERVICE_NO_CHANGE = 0xffffffff
; //這個值可以在 winsvc.h 中找到 private const uint SERVICE_QUERY_CONFIG = 0x00000001; private const uint SERVICE_CHANGE_CONFIG = 0x00000002; [DllImport("advapi32.dll",CharSet = CharSet.Unicode,SetLastError = true)] public static extern Boolean ChangeServiceConfig(IntPtr hService,UInt32 nServiceType,UInt32 nStartType,UInt32 nErrorControl,String lpBinaryPathName,String lpLoadOrderGroup,IntPtr lpdwTagId,[In]
char[] 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)] public static extern IntPtr OpenSCManager(string machineName,string databaseName,uint dwAccess); public static bool ChangeServiceAccountInfo(string serviceName,string username,string password) { try { IntPtr scm_Handle = OpenSCManager(null,null,SC_MANAGER_ALL_ACCESS); if (scm_Handle == IntPtr.Zero) throw new System.Runtime.InteropServices.ExternalException("開啟服務管理器錯誤"); IntPtr service_Handle = OpenService(scm_Handle,serviceName,SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); if (service_Handle == IntPtr.Zero) throw new System.Runtime.InteropServices.ExternalException("開啟服務錯誤");
//修改服務的賬戶使用者名稱和密碼 if (!ChangeServiceConfig(service_Handle,SERVICE_NO_CHANGE,null,null,IntPtr.Zero,username,password,null)) { int nError = Marshal.GetLastWin32Error(); Win32Exception win32Exception = new Win32Exception(nError); throw new System.Runtime.InteropServices.ExternalException("無法修改服務登入身份的使用者名稱和密碼:" + win32Exception.Message); } Console.WriteLine("服務登入身份資訊修改成功!"); return true; } catch (Exception ex) { Console.WriteLine(ex.ToString()); return false; } }

2、使用 C# 中 WMI 修改服務登入身份資訊:

使用 WMI 服務,我們需要新增 System.Management 的引用。

注意:如果您的遠端計算機連線的是 Active Directory 域,那麼使用完全限定的使用者名稱(例如 TestDomainMorgan)而不是簡單的使用者名稱(Morgan)。

using System.Management;

public static void ChangeServiceAccountInfobyWMI(string serviceName,string password)
{
    string mgmntPath = string.Format("Win32_Service.Name=‘{0}‘",serviceName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(mgmntPath)))
    {
        object[] accountParams = new object[11];
        accountParams[6] = username;
        accountParams[7] = password;
        uint returnCode = (uint)service.InvokeMethod("Change",accountParams);
        if (returnCode == 0)
        {
             Console.WriteLine("服務登入身份資訊修改成功!");
        }
        else
        {
             Console.WriteLine("服務登入身份資訊修改失敗");
             Console.WriteLine("錯誤程式碼:" + returnCode);
             // 此微軟官方支援連結,可以檢視相應的返回程式碼的訊息:
             // https://msdn.microsoft.com/en-us/library/aa393660(v=vs.85).aspx
        }
    }
}

3、使用 C#中的 WMI 修改遠端計算機服務的登入身份資訊:

使用 WMI 服務,我們需要新增 System.Management 的引用,並且在修改遠端計算機中的服務資訊時,請使用管理員憑據。

注意:如果您的遠端計算機連線的是 Active Directory 域,那麼使用完全限定的使用者名稱(例如 TestDomainMorgan)而不是簡單的使用者名稱(Morgan)。

using System.Management;
static void ChangeRemoteServiceAccountInfo(string remoteComputer,string serviceName,string username,string password) { try { ConnectionOptions connectionOptions = new ConnectionOptions(); // 如需要,請使用證書 //connectionOptions.Username = "Administrator"; //connectionOptions.Password = "AdminPassword"; //connectionOptions.Impersonation = ImpersonationLevel.Impersonate; ManagementScope scope = new ManagementScope("\" + remoteComputer + "rootCIMV2",connectionOptions); scope.Connect(); string mgmntPath = string.Format("Win32_Service.Name=‘{0}‘",serviceName); using (ManagementObject service = new ManagementObject(scope,new ManagementPath(mgmntPath),new ObjectGetOptions())) { object[] accountParams = new object[11]; accountParams[6] = username; accountParams[7] = password; uint returnCode = (uint)service.InvokeMethod("Change",accountParams); if (returnCode == 0) { Console.WriteLine("服務登入身份資訊修改成功!"); } else { Console.WriteLine("服務登入身份資訊修改失敗"); Console.WriteLine("錯誤程式碼:" + returnCode); // 此微軟官方支援連結,可以檢視相應的返回程式碼資訊: // https://msdn.microsoft.com/en-us/library/aa393660(v=vs.85).aspx } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }

原創出處:https://morgantechspace.com/2015/03/csharp-change-service-account-username-and-password.html