我是一名专业程序员,因此,我不知道我在做什么:)
严肃地说;不,我不是专家。我确实有问题,不知道如何解决它。好消息是,我(我想)知道问题是什么,我希望有人可以提供帮助。
这是问题的概要。我在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和密码传递给此服务器以便进行身份验证或运行,以便我可以检查这些服务的状态,这就是问题所在。如果有人不认为这个问题,那么请告诉我我哪里出错了:)
答案 0 :(得分:10)
终于想通了......
创建了一个新类,如下所示:
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();