当前位置:  开发笔记 > 编程语言 > 正文

.Net 2.0 ServiceController.GetServices()

如何解决《.Net2.0ServiceController.GetServices()》经验,为你挑选了1个好方法。

我有一个网站,它启用了Windows身份验证.从网站中的页面,用户可以启动一项服务,该服务可以对数据库执行一些操作.

它适用于我启动服务,因为我是服务器上的本地管理员.但我只是有一个用户测试它,他们无法启动服务.

我的问题是:


有没有人知道如何通过名称使用与当前登录时不同的Windows帐户获取指定计算机上的服务列表?


我真的不想将需要启动服务的所有用户添加到一个Windows组中,并将它们全部设置为我的IIS服务器上的本地管理员.....

这是我得到的一些代码:

public static ServiceControllerStatus FindService()
        {
            ServiceControllerStatus status = ServiceControllerStatus.Stopped;

            try
            {
                string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
                ServiceController[] services = ServiceController.GetServices(machineName);
                string serviceName = ConfigurationManager.AppSettings["ServiceName"].ToLower();

                foreach (ServiceController service in services)
                {
                    if (service.ServiceName.ToLower() == serviceName)
                    {
                        status = service.Status;
                        break;
                    }
                }
            }
            catch(Exception ex)
            {
                status = ServiceControllerStatus.Stopped;
                SaveError(ex, "Utilities - FindService()");
            }

            return status;
        }

我的例外来自try块中的第二行.这是错误:

System.InvalidOperationException:无法在计算机'server.domain.com'上打开服务控制管理器.此操作可能需要其他权限.---> System.ComponentModel.Win32Exception:拒绝访问---内部异常堆栈跟踪的结束---在System.ServiceProcess.ServiceController.GetServicesOfType(String)处的System.ServiceProcess.ServiceController.GetDataBaseHandleWithAccess(String machineName,Int32 serviceControlManaqerAccess)处telemarketingWebSite.Utilities.StartService()上的machineName,Int32 serviceType)

感谢您的帮助/信息



1> Charlie..:

注意:这并不是将服务枚举为不同的用户,但考虑到您正在做的更广泛的描述,我认为这是一个很好的答案.

如果您直接访问感兴趣的服务,我认为您可以简化这一过程,并可能避免部分安全问题.试试这个,而不是调用GetServices:

string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
string serviceName = ConfigurationManager.AppSettings["ServiceName"];
ServiceController service = new ServiceController( serviceName, machineName );
return service.Status;

这直接连接到感兴趣的服务并绕过枚举/搜索步骤.因此,它不需要调用者SC_MANAGER_ENUMERATE_SERVICE在服务控制管理器(SCM)上拥有权限,默认情况下远程用户没有.它仍然需要SC_MANAGER_CONNECT,但根据MSDN,应该授予远程认证用户.

一旦找到感兴趣的服务,您仍然需要能够停止并启动它,远程用户可能无权执行此操作.但是,可以修改单个服务上的安全描述符(DACL),这样您就可以授予远程用户访问权限以停止和启动服务,而无需他们成为本地管理员.这是通过SetNamedSecurityInfo API函数完成的.您需要授予的访问权限是SERVICE_STARTSERVICE_STOP.根据这些用户所属的确切组,您可能还需要授予它们GENERIC_READ.所有这些权利都在MSDN中描述.

这是一些将执行此设置的C++代码,假设感兴趣的用户位于"远程服务控制器"组(您将创建)中,并且服务名称为"my-service-name".请注意,如果您要授予对诸如用户(不一定是个好主意)之类的知名组的访问权限,而不是您创建的组,则需要更改TRUSTEE_IS_GROUPTRUSTEE_IS_WELL_KNOWN_GROUP.

代码没有错误检查,您可以添加.可能失败的所有三个函数(Get/SetNamedSecurityInfo和SetEntriesInAcl)返回0表示成功.

另请注意:您还可以使用SC工具设置服务的安全描述符,该工具可以在%WINDIR%\ System32下找到,但不涉及任何编程.

#include "windows.h"
#include "accctrl.h"
#include "aclapi.h"

int main()
{
    char serviceName[] = "my-service-name";
    char userGroup[] = "Remote Service Controllers";

    // retrieve the security info
    PACL pDacl = NULL;
    PSECURITY_DESCRIPTOR pDescriptor = NULL;
    GetNamedSecurityInfo( serviceName, SE_SERVICE,
        DACL_SECURITY_INFORMATION, NULL, NULL,
        &pDacl, NULL, &pDescriptor );

    // add an entry to allow the users to start and stop the service
    EXPLICIT_ACCESS access;
    ZeroMemory( &access, sizeof(access) );
    access.grfAccessMode = GRANT_ACCESS;
    access.grfAccessPermissions = SERVICE_START | SERVICE_STOP;
    access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    access.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    access.Trustee.ptstrName = userGroup;
    PACL pNewDacl;
    SetEntriesInAcl( 1, &access, pDacl, &pNewDacl );

    // write the changes back to the service
    SetNamedSecurityInfo( serviceName, SE_SERVICE,
        DACL_SECURITY_INFORMATION, NULL, NULL,
        pNewDacl, NULL );

    LocalFree( pNewDacl );
    LocalFree( pDescriptor );
}

这也可以通过P/Invoke从C#完成,但这需要更多的工作.

如果您仍然特别希望能够以这些用户的身份枚举服务,则需要SC_MANAGER_ENUMERATE_SERVICE在SCM上授予他们权限.不幸的是,根据MSDN,SCM的安全性只能在Windows Server 2003 sp1或更高版本上进行修改.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有