以编程方式安装Windows服务

时间:2013-11-06 15:44:54

标签: .net winapi windows-services

我按照here的步骤安装了Windows服务。

1.像这样构建服务的Main()函数

static void Main(string[] args)
{
    if (args.Length == 0) {
       // Run your service normally.
       ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
       ServiceBase.Run(ServicesToRun);
     } else if (args.Length == 1) {
       switch (args[0]) {
           case "-install":
              InstallService();
              StartService();
              break;
           case "-uninstall":
              StopService();
              UninstallService();
              break;
           default:
              throw new NotImplementedException();
      }
   }
} 

2。支持代码如下

public static bool  InstallService(string svcPath, string svcName, string svcDispName)
    {
        #region Constants declaration.
        int SC_MANAGER_CREATE_SERVICE = 0x0002;
        int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
        //int SERVICE_DEMAND_START = 0x00000003;
        int SERVICE_ERROR_NORMAL = 0x00000001;
        int STANDARD_RIGHTS_REQUIRED = 0xF0000;
        int SERVICE_QUERY_CONFIG = 0x0001;
        int SERVICE_CHANGE_CONFIG = 0x0002;
        int SERVICE_QUERY_STATUS = 0x0004;
        int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
        int SERVICE_START = 0x0010;
        int SERVICE_STOP = 0x0020;
        int SERVICE_PAUSE_CONTINUE = 0x0040;
        int SERVICE_INTERROGATE = 0x0080;
        int SERVICE_USER_DEFINED_CONTROL = 0x0100;
        int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
        SERVICE_QUERY_CONFIG |
        SERVICE_CHANGE_CONFIG |
        SERVICE_QUERY_STATUS |
        SERVICE_ENUMERATE_DEPENDENTS |
        SERVICE_START |
        SERVICE_STOP |
        SERVICE_PAUSE_CONTINUE |
        SERVICE_INTERROGATE |
        SERVICE_USER_DEFINED_CONTROL);
        int SERVICE_AUTO_START = 0x00000002;
        #endregion Constants declaration.
        try
        {
            IntPtr sc_handle = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
            if (sc_handle.ToInt32() != 0)
            {
                IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);
                if (sv_handle.ToInt32() == 0)
                {
                    CloseServiceHandle(sc_handle);
                    return false;
                }
                else
                {
                    //now trying to start the service
                    int i = StartService(sv_handle, 0, null);
                    // If the value i is zero, then there was an error starting the service.
                    // note: error may arise if the service is already running or some other problem.
                    if (i == 0)
                    {
                        Console.WriteLine("Couldnt start service");
                        return false;
                    }
                    Console.WriteLine("Service started successfully");
                    CloseServiceHandle(sc_handle);
                    return true;
                }
            }
            else
            {
                Console.WriteLine("SCM not opened successfully");
                return false;
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }

然后我在bin / debug文件夹xxx.exe -install

中运行命令

一切都很好,服务已成功部署。 但问题是我必须在调试文件夹中运行命令,我想这是因为它包含一堆dll。如果我将可执行文件仅移动到其他位置并进行安装。抛出异常,

System.IO.FileNotFoundException: Could not load file or assembly  'VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

我不知道为什么安装代码正在寻找dll,因为我认为exe文件包含它。

代码在

运行时是否存在问题
IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);

它试图在调试文件夹中找到程序集?

1 个答案:

答案 0 :(得分:-2)

如果你想以编程方式安装你的服务,你可以做这样的事情(对我来说很简单,就像魅力一样):

static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            if (args[0].Equals("/i", StringComparison.InvariantCultureIgnoreCase))
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(new string[] {
                    System.Reflection.Assembly.GetExecutingAssembly().Location});
            }
            else if (args[0].Equals("/u", StringComparison.InvariantCultureIgnoreCase))
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(new string[] {"/u",
                    System.Reflection.Assembly.GetExecutingAssembly().Location});
            }
        }
        else
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new MyService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }