4

我们有一个我们创建的服务(并在我们的一个服务器上运行),我想通过另一个程序来控制它。我在服务方面遇到了一些困难,希望有人能提供帮助。

如果我尝试使用以下路由控制服务,它也仅适用于服务器上的用户:

ServiceController service = new ServiceController("MyService", "MyServer");

try
{
    if (service.Status == ServiceControllerStatus.Running)
    {
        teServiceStatus.BackColor = Color.LightGreen;
        teServiceStatus.Text = "Running";
        sbStartService.Enabled = false;
        sbStopService.Enabled = true;
    }
    else
    {
        teServiceStatus.BackColor = Color.Red;
        teServiceStatus.Text = "Stopped";
        sbStartService.Enabled = true;
        sbStopService.Enabled = false;
    }
}
catch (InvalidOperationException ioe)
{
    if (System.Diagnostics.Debugger.IsAttached)
        System.Diagnostics.Debugger.Break();
    else
    {
        teServiceStatus.Text = "Cannot Connect";
        teServiceStatus.BackColor = Color.Red;
    }
}
catch (Exception ex)
{
    if (System.Diagnostics.Debugger.IsAttached)
        System.Diagnostics.Debugger.Break();
    else
        ;
}

因此,作为网络用户,我也以用户身份在服务器上,当我运行想要控制此服务的程序时,我可以看到状态并启动和停止它,但没有其他人可以(除非我将它们添加到服务器,我不想这样做)。

我还可以使用下面的路由并在服务器上模拟用户:

//Establish connection to the Publishing Server with application credentials.
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
connectionOptions.EnablePrivileges = true;
connectionOptions.Username = "UserOnServer";
connectionOptions.Password = "UserPassword";
ManagementScope managementScope = new ManagementScope(@"\\MyServer\root\cimv2", connectionOptions);
managementScope.Connect();

ManagementPath path = new ManagementPath("Win32_Service");
ManagementClass services = new ManagementClass(managementScope, path, null);

foreach (ManagementObject service in services.GetInstances())
{
    try
    {
        if (service.GetPropertyValue("Name").ToString() == "MyService")
            if (service.GetPropertyValue("State").ToString().ToLower().Equals("running"))
            {
                teServiceStatus.BackColor = Color.LightGreen;
                teServiceStatus.Text = "Running";
                sbStartService.Enabled = false;
                sbStopService.Enabled = true;
            }
            else
            {
                teServiceStatus.BackColor = Color.Red;
                teServiceStatus.Text = "Stopped";
                sbStartService.Enabled = true;
                sbStopService.Enabled = false;
            }
    }
    catch (InvalidOperationException ioe)
    {
        if (System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
        else
        {
            teServiceStatus.Text = "Cannot Connect";
            teServiceStatus.BackColor = Color.Red;
        }
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
        else
        {
            teServiceStatus.Text = "Cannot Connect";
            teServiceStatus.BackColor = Color.Red;
        }
    }
} 

这样可以使任何使用该程序的用户都可以启动/停止服务并查看它的当前状态但是,当程序关闭时,服务停止(不知道这是否应该发生,但确实如此)。

那么,如何让我的程序启动、停止和读取任何使用它的人的服务状态呢?我觉得我很接近,但显然,错过了一些东西。

更新 使用 ConnectionOptions 路由时,似乎只要 ConnectionOptions(或 ManagementScope)所在的表单关闭,然后服务器将其记录为登录用户已“注销”,并在该处关闭服务时间。我不知道为什么,但仍然试图调查它。

4

1 回答 1

0

让您正在运行的客户端代码模拟该NT AUTHORITY\NetworkService帐户,使其具有与您的服务相同的权限级别。该帐户的密码为空(或者可能是空字符串,我猜都试试)。WindowsIdentity.Impersonate中演示了有关如何在模拟该用户时运行代码的文档。有关模拟/委托的更多信息。

此外,您可能希望为服务中的所有未处理异常实现处理程序。有可能在您的 try/catch 块之外引发异常,这就是为什么您的应用程序退出而您的附加调试器没有在您的 catch 块中设置的任何断点上中断。

于 2012-07-09T20:20:41.100 回答