这是我的Windows/.净安全栈:

  • Windows服务的运行为本地系统上的Windows服务器2003框。
  • A.净3.5网站上运行的相同框,在"默认"生产服务器IIS设置的(因此可能作为网络服务的用户?)

在我的默认VS2008开发环境的我有这样的一个方法,该方法被称为从ASP.NET 应用程序,其工作:

private static void StopStartReminderService() {

    ServiceController svcController = new ServiceController("eTimeSheetReminderService");

    if (svcController != null) {
        try {
            svcController.Stop();
            svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
            svcController.Start();
        } catch (Exception ex) {
            General.ErrorHandling.LogError(ex);
        }
    }
}

当我运行这个生产服务器上,我得到的以下错误,从ServiceController:

资料来源:系统。ServiceProcess-> 系统。ServiceProcess.ServiceController->因此 GetServiceHandle(Int32)->系统。InvalidOperationException信息:不能打开eTimeSheetReminderService服务在电脑上'.'.

为什么会出现这种情况,以及如何解决这个问题?

编辑:

答案是以下,主要是在评论,但澄清:

  1. 问题是安全相关的,并以发生,是因为该网络服务帐户中没有足够的权利来开始停服务
  2. 我创建了一个本地用户账户,并将其添加到超级用户小组(该小组几乎具有管理员权利)
  3. 我不想我的整个网络的应用程序模拟用户所有的时间,所以我冒充唯一的方法我在哪里操纵的服务。我这样做是通过使用以下资源来帮助我做到这一点在代码:

MS KB的文章这只是为了得到更好的理解

注: 我不模拟通过网络。config,我做它的代码。看MS KB文所述。

有帮助吗?

解决方案

尝试加入这对你网。Config。

<identity impersonate="true"/>

其他提示

给IIS许可以启动/停止的一种特殊的服务:

  • 下载,安装 Subinacl.exe. (一定要得到最新的版本!早期版本分发,在一些资源工具包中不工作!)
  • 发出类似的命令: subinacl /service {yourServiceName} /grant=IIS_WPG=F

这给予充分业务控制权这一特定服务的内在IIS_WPG组。(这适用于IIS6/Win2k3.) 情况因人而异的较新版本IIS。)

这是一个很好的问题很感兴趣,我...

因此,这里是我做了什么来解决这个问题:

  • 步骤1:创建一个Windows用户账户在当地的机与最小的权利。
  • 步骤2:得到这种用户权利开始,并停止通过服务subinacl.exe
  • 即subinacl.exe /服务WindowsServiceName/授予=PCNAME estUser=STOE
  • 下载自: http://www.microsoft.com/en-za/download/details.aspx?id=23510
  • 步骤3:使用模拟模拟使用创建的步骤1的启动和中止的服务

    public const int LOGON32_PROVIDER_DEFAULT = 0;
    
    WindowsImpersonationContext _impersonationContext;
    
    [DllImport("advapi32.dll")]
    // ReSharper disable once MemberCanBePrivate.Global
    public static extern int LogonUserA(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    // ReSharper disable once MemberCanBePrivate.Global
    public static extern int DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);
    
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    // ReSharper disable once MemberCanBePrivate.Global
    public static extern bool RevertToSelf();
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    // ReSharper disable once MemberCanBePrivate.Global
    public static extern bool CloseHandle(IntPtr handle);
    
    private bool _impersonate;
    
    public bool ImpersonateValidUser(String userName, String domain, String password)
    {
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;
    
        if (RevertToSelf())
        {
            if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            {
                if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                {
                    var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                    _impersonationContext = tempWindowsIdentity.Impersonate();
                    if (_impersonationContext != null)
                    {
                        CloseHandle(token);
                        CloseHandle(tokenDuplicate);
                        _impersonate = true;
                        return true;
                    }
                }
            }
        }
        if (token != IntPtr.Zero)
            CloseHandle(token);
        if (tokenDuplicate != IntPtr.Zero)
            CloseHandle(tokenDuplicate);
        _impersonate = false;
        return false;
    }
    
    #region Implementation of IDisposable
    
    
    
    
    #endregion
    
    #region Implementation of IDisposable
    
    private void Dispose(bool dispose)
    {
        if (dispose)
        {
            if (_impersonate)
                _impersonationContext.Undo();
            _impersonationContext.Dispose();
        }
    }
    
    public void Dispose()
    {
        Dispose(true);
    }
    #endregion
    
    public static void StartStopService(bool startService, string serviceName)
    {
        using (var impersonateClass = new Impersonation())
        {
            impersonateClass.ImpersonateValidUser(Settings.Default.LocalUsername, Settings.Default.Domain, Settings.Default.Password);
            using (var sc = new ServiceController(serviceName))
            {
                if (startService)
                    sc.Start();
                else if (sc.CanStop)
                    sc.Stop();
            }
    
        }
    }
    

更新IIS8(以及或许一些稍早期版本)

对用户组 IIS_WPG 不存在了。它已经改变了 IIS_IUSRS.

此外,开始停止服务,它不是需要给予充分的权限(F)。权限的开始、停止和暂停服务(TOP)应该是足够的。因此,该命令应为:

subinacl/服务{yourServiceName}/授予=IIS_IUSRS=顶

注意,你需要点命令提示(最高为管理员) C:\Windows\System32 文件夹在运行这一命令。

还要确保你复制的subinacl.exe 文件 C:\Windows\System32 从安装目录,如果有一个错误。

只是一个直觉,但是它不会出现我的错误是必然关系到安全。你有没有得到服务的相同姓名在生产服务器上?

如果你网络应用程序的数据库和windows服务可以访问它,你就可以使用该标志的数据库,以重新启动服务。在服务中,你可以读这标志和重新启动,如果不忙等。只有在情况下,如果你可以修改码的服务。如果是第三方服务,您可以创建自己的windows服务和使用数据库的配置来控制(重新)的服务。这是安全的方式,并为您提供了更多的灵活性和安全性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top