2016-01-21 56 views
6

获取异常与此代码启动或停止IIS,也是一个Windows服务... eventhough我在远程机器如何在远程机器上使用C#

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); 
     } 
    } 

异常管理员权限:

“System.InvalidOperationException”类型的未处理的异常出现在System.ServiceProcess.dll

其他信息:无法打开服务C ontrol Manager '10.201.58.114'。此操作可能需要其他权限。

+0

目标系统是否没有安全软件?你会发现一些安全软件可以产生这种效果。 – Xefan

+1

它会帮助运行应用程序“作为管理员”?还假设你有权提供IP ... – vidriduch

+0

使用以管理员身份使用命令提示符:'C:\> iisreset。exe <远程计算机的IP地址>,错误信息为:'访问被拒绝,您必须是远程计算机的管理员才能使用此命令。您的帐户可以添加到管理员本地组 远程计算机或域管理员全局组。“请注意,我拥有远程计算机的管理员权限,但仍然出现错误。 – venkat

回答

0

听起来像是如果用户是你是不是添加到本地组管理员

入住这与

净本地管理员

远程机器

上不在列表中,运行

净本地管理员/添加用户

+0

我的名字已经列在本地管理员组中。但仍然得到相同的例外。 – venkat

1

是在同一个域中的机器?如果不是机器1上的Administrator与机器2上的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(); 

     } 
    } 

} 

确保远程机器可以使用评估提供的凭据尝试做到这一点的代码如前通过远程桌面连接成这个用户。

+0

**错误**:无法找到类型或名称空间名称'RemoteAccessHelper'(您是否缺少using指令或程序集引用?)' – venkat

+0

您是否看过本教程中的代码http:// dotnet- assembly.blogspot.com.au/2012/11/c-accessing-remote-file-by-using.html –

+0

所以只是为了澄清1)确定远程计算机的计算机/域名2)尝试连接到远程机器从您的代码运行的机器使用该计算机/域名以及代码之外的用​​户名和密码,例如使用远程桌面3)如果成功,请根据本教程中的代码尝试C#模拟。另外,你确定你是否在域名?如果两台机器都在同一个域中,则可能会出现其他问题。 –

相关问题