gpt4 book ai didi

c# - 如何使用 C# 启动或停止 IIS 以及远程计算机中的 Windows 服务

转载 作者:太空狗 更新时间:2023-10-29 21:56:57 24 4
gpt4 key购买 nike

使用此代码获取异常...即使我在远程计算机中拥有管理员权限

class Program
{
static void Main(string[] args)
{
var sc = new System.ServiceProcess.ServiceController("W3SVC", "10.201.58.114");
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
}

异常:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceProcess.dll

Additional information: Cannot open Service Control Manager on computer '10.201.58.114'. This operation might require other privileges.

最佳答案

机器是否在同一个域中?如果 machine1 上的 Administrator 不是 machine2 上的 Administrator,那么这可能是您的问题。

一种可能是您需要授予此用户访问权限 - 在远程计算机上 - 以停止和启动服务,如下所示:

SUBINACL /SERVICE \\<MACHINE>\W3SVC /GRANT=<MACHINE>\<USER>=TO

下面第二个代码块的注释中有一个这样的例子(因为即使使用代码内身份模拟我也需要这个)。

如果这不能解决问题,您可以尝试模拟远程用户。我设法使用以下代码让它工作。

首先,新建一个类WrapperImpersonationContext.cs:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.ComponentModel;

//Version from http://michiel.vanotegem.nl/2006/07/windowsimpersonationcontext-made-easy/

public class WrapperImpersonationContext
{
[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 const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;

private string m_Domain;
private string m_Password;
private string m_Username;
private IntPtr m_Token;

private WindowsImpersonationContext m_Context = null;


protected bool IsInContext
{
get { return m_Context != null; }
}

public WrapperImpersonationContext(string domain, string username, string password)
{
m_Domain = domain;
m_Username = username;
m_Password = password;
}

[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Enter()
{
if (this.IsInContext) return;
m_Token = new IntPtr(0);
try
{
m_Token = IntPtr.Zero;
bool logonSuccessfull = LogonUser(
m_Username,
m_Domain,
m_Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref m_Token);
if (logonSuccessfull == false)
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
WindowsIdentity identity = new WindowsIdentity(m_Token);
m_Context = identity.Impersonate();
}
catch (Exception exception)
{
// Catch exceptions here
}
}


[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Leave()
{
if (this.IsInContext == false) return;
m_Context.Undo();

if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
m_Context = null;
}
}

然后您应该能够运行以下命令。请注意,您需要更改机器名、用户名和密码以匹配您的设置。还要注意评论,因为我在此过程中发现了重要的安全设置信息:

//Code for Program.cs demonstrating the identity impersonation for a ServiceController.

using System;
using System.Security.Principal;
using System.ServiceProcess;

namespace RemoteConnectionTest
{
class MainClass
{
public static void Main (string[] args)
{

try {

//Based on the code from http://michiel.vanotegem.nl/2006/07/windowsimpersonationcontext-made-easy/

Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);
//Also worked with the IP address of GARNET (which was the machine name).
WrapperImpersonationContext context = new WrapperImpersonationContext("GARNET", "TestAdmin1", "password123");
context.Enter();
// Execute code under other uses context
Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);

// Code to execute.

//Try running the following command on the remote server first to ensure
//the user has the appropriate access (obviously substitute the
//username and machine name).
// runas /user:TestAdmin "sc \\GARNET stop W3SVC"

//Also, make sure the user on the remote server has access for
//services granted as described here: http://stackoverflow.com/a/5084563/201648
//Otherwise you may see an error along the lines of:
//Cannot open W3SVC service on computer '<SERVER>'. ---> System.ComponentModel.Win32Exception: Access is denied
//For my configuration I had to run the command:
// SUBINACL /SERVICE \\GARNET\W3SVC /GRANT=GARNET\TestAdmin=TO
//It's entirely possible that running this command will allow your existing code to work without using impersonation.

//You may need to install SUBINACL https://www.microsoft.com/en-au/download/details.aspx?id=23510
//By default SUBINACL will install to C:\Program Files (x86)\Windows Resource Kits\Tools
//so CD to that directory and then run the SUBINACL command above.

//Also worked with the IP address of GARNET (which was the machine name).
var sc = new ServiceController("W3SVC", "GARNET");
sc.Start();

sc.WaitForStatus(ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped);

//END - code to execute.
context.Leave();
Console.WriteLine("Your code ran successfully. Current user: " + WindowsIdentity.GetCurrent().Name);

} catch (Exception ex) {
Console.WriteLine("An exception occured - details as follows: {0}", ex.Message);
Console.WriteLine("The full stack trace is: {0}", ex);
}

Console.WriteLine ("Press any key to exit...");
Console.ReadLine();

}
}

}

在您尝试在代码中执行此操作之前,请确保可以使用提供的凭据评估远程机器,例如通过远程桌面以该用户身份连接。

关于c# - 如何使用 C# 启动或停止 IIS 以及远程计算机中的 Windows 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34919343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com