远程计算机上的C#服务状态

我是一名专家程序员,因此,我不知道我在做什么:)

严肃地说; 不,我不是专家。 我确实有问题,不知道如何解决它。 好消息是,我(我想)知道问题是什么,我希望有人可以提供帮助。

这是问题的概要。 我在C#中创建一个表单,它将为我做一些服务器和数据库管理任务。 我有一个按钮,当点击时,应该在“y”服务器上返回“x”服务的服务状态。 状态将在屏幕上打印到文本框。

这是我的代码:

private void button2_Click(object sender, EventArgs e) { string fs = "Service X Status = "; string mr = "Service A Status = "; string qp = "Service B Status = "; string sp = "Spooler Service Status = "; ServiceController fssc = new ServiceController("xService", "yServer"); ServiceController mrsc = new ServiceController("aService", "yServer"); ServiceController qpsc = new ServiceController("bService", "yServer"); ServiceController spsc = new ServiceController("Spooler", "yServer"); try { txtGtwySts.AppendText(sp + spsc.Status.ToString()); txtGtwySts.AppendText(Environment.NewLine); txtGtwySts.AppendText(fs + fssc.Status.ToString()); txtGtwySts.AppendText(Environment.NewLine); txtGtwySts.AppendText(mr + mrsc.Status.ToString()); txtGtwySts.AppendText(Environment.NewLine); txtGtwySts.AppendText(qp + qpsc.Status.ToString()); } catch (Exception crap) { string msg = ""; int i; for (i = 0; i < crap.Message.Count(); i++) { msg += "Error # " + i + " Message: " + crap.Message + "\n"; } MessageBox.Show(msg); MessageBox.Show(i.ToString()); } } 

我得到例外,基本上说:无法在“服务器”上打开“服务”。 由于这是一个远程服务器,我假设这是一个凭证/安全问题。 但是,我不会对后台打印程序服务有任何问题。

我的问题是……如何将userID和密码传递给这个服务器,以便它进行身份validation或运行,这样我就可以检查这些服务的状态,这就是问题所在。 如果有人不认为它的问题,那么请告诉我我哪里出错了:)

终于想通了……

创建了一个新类,如下所示:

 using System; using System.Collections.Generic; using System.Text; using System.Security.Principal; using System.Runtime.InteropServices; using System.Security.Permissions; public class ImpersonateUser { [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser( String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); private static IntPtr tokenHandle = new IntPtr(0); private static WindowsImpersonationContext impersonatedUser; // If you incorporate this code into a DLL, be sure to demand that it // runs with FullTrust. [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] public void Impersonate(string domainName, string userName, string password) { //try { // Use the unmanaged LogonUser function to get the user token for // the specified user, domain, and password. const int LOGON32_PROVIDER_DEFAULT = 0; // Passing this parameter causes LogonUser to create a primary token. const int LOGON32_LOGON_INTERACTIVE = 2; tokenHandle = IntPtr.Zero; // ---- Step - 1 // Call LogonUser to obtain a handle to an access token. bool returnValue = LogonUser( userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle); // tokenHandle - new security token if (false == returnValue) { int ret = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(ret); } // ---- Step - 2 WindowsIdentity newId = new WindowsIdentity(tokenHandle); // ---- Step - 3 { impersonatedUser = newId.Impersonate(); } } } // Stops impersonation public void Undo() { impersonatedUser.Undo(); // Free the tokens. if (tokenHandle != IntPtr.Zero) { CloseHandle(tokenHandle); } } } 

}

我发布的原始代码包含在:

 ImpersonateUser iu = new ImpersonateUser(); iu.Impersonate("[domain]","[username]","[password]"); // code you want to execute as impersonated user..... iu.Undo();