首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >您可以通过编程方式更改现有Windows服务的显示名称(和其他属性)吗?

您可以通过编程方式更改现有Windows服务的显示名称(和其他属性)吗?
EN

Stack Overflow用户
提问于 2015-04-04 00:51:24
回答 2查看 219关注 0票数 2

我希望用户能够使用我们的配置工具更改现有Windows服务的显示名称。在代码中,给定相应ServiceController对象的一个实例,设置其DisplayName属性似乎是有效的。已尝试调用Refresh,但似乎没有效果。MSDN文档对Refresh的作用有点不清楚--它是重新读取当前的服务设置,还是将我的更改写入服务?代码很简单:

代码语言:javascript
复制
ServiceController sc = GetServiceController(CurrentInterfaceData.ServiceName);
sc.DisplayName = "MyService";
sc.Refresh();
EN

回答 2

Stack Overflow用户

发布于 2015-04-04 04:05:39

使用WMI。为此,您必须添加对System.Management程序集的引用。以下是我用于通用安装程序的工作代码的摘录:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        UpdateService("ipsecd");
    }

    private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
    private const int LOGON32_PROVIDER_WINNT50 = 3;
    private const int SERVICE_ALL_ACCESS = 0xF01FF;
    private const int SC_MANAGER_ALL_ACCESS = 0xF003F;
    private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
    private const uint SERVICE_WIN32_OWN_PROCESS = 0x00000010;
    private const uint SERVICE_INTERACTIVE_PROCESS = 0x00000100;
    // Win32 function to connect to remote machine
    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern Boolean LogonUser(string lpUsername, string lpDomain, string lpPassword, int dwLogonType,
                                            int dwLogonProvider, out IntPtr phToken);

    // Win32 function to connect to impersonate user
    [DllImport("advapi32.dll", SetLastError = true)]
    static extern int ImpersonateLoggedOnUser(IntPtr hToken);

    // Win32 function to open the service control manager
    [DllImport("advapi32.dll")]
    private static extern IntPtr OpenSCManager(string lpMachineName, string lpDatabaseName, int dwDesiredAccess);

    // Win32 function to open a service instance
    [DllImport("advapi32.dll")]
    private static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, int dwDesiredAccess);

    // Win32 function to change the service config
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern Boolean ChangeServiceConfig(
        IntPtr hService,
        UInt32 nServiceType,
        UInt32 nStartType,
        UInt32 nErrorControl,
        String lpBinaryPathName,
        String lpLoadOrderGroup,
        IntPtr lpdwTagId,
        [In] char[] lpDependencies,
        String lpServiceStartName,
        String lpPassword,
        String lpDisplayName);


    public static void UpdateService(string serviceName)
    {
        ManagementScope scope = null;            
        ObjectQuery filter = new ObjectQuery(string.Format("SELECT * FROM Win32_Service WHERE Name = '{0}'", serviceName));
        ManagementObjectSearcher query = new ManagementObjectSearcher(scope, filter);
        try
        {
            ManagementObjectCollection services = query.Get();
            // No match = failed condition
            if (services.Count == 0)                
                return;
            foreach (ManagementObject service in services)
            {
                SetServiceDisplayName(serviceName, "new disp name");
                service.Dispose();
            }
        }
        catch (Exception ex)
        {
            //Could not set property
        }

    }

    private static void SetServiceDisplayName(string name, string dispName)
    {            
        IntPtr svcHndl = OpenService("", "", name);
        // Call the ChangeServiceFailureActions() abstraction of ChangeServiceConfig2()
        bool rslt = ChangeServiceConfig(svcHndl, SERVICE_NO_CHANGE,
            SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, null, null, dispName);            
    }

    private static IntPtr OpenService(string userName, string password, string serviceName)
    {
        IntPtr scmHndl = IntPtr.Zero;
        IntPtr svcHndl = IntPtr.Zero;
        // Open the service control manager
        scmHndl = OpenSCManager("", null, SC_MANAGER_ALL_ACCESS);

        if (scmHndl.ToInt32() <= 0)
            return IntPtr.Zero;

        // Open the service
        svcHndl = OpenService(scmHndl, serviceName, SERVICE_ALL_ACCESS);

        if (svcHndl.ToInt32() <= 0)
            return IntPtr.Zero;

        return svcHndl;
    }
}

试试看。应该能行得通。

票数 1
EN

Stack Overflow用户

发布于 2015-04-04 01:06:23

我相信Windows服务的名称是在安装服务时设置的。我不认为稍后更改它会有任何影响。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29436364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档