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

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

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)所在的窗体,将其关闭,然后服务器将其记录为已登录用户已“注销”,然后关闭该服务。 。我不知道为什么,但仍在尝试研究。

最佳答案

让正在运行的客户端代码模拟NT AUTHORITY\NetworkService帐户,使其具有与服务相同级别的权限。该帐户的The password is null(或者可能是空字符串,请尝试两种方式)。 WindowsIdentity.Impersonate中演示了有关在模拟用户时如何运行代码的文档。有关更多信息,请参见Impersonation/Delegation

另外,您可能想在服务中实现handlers for all unhandled exceptions。可能在try / catch块之外引发了异常,这就是为什么您的应用程序正在退出而您的附加调试器没有在catch块中设置的任何断点中断的原因。

07-28 02:19
查看更多