zoukankan      html  css  js  c++  java
  • 把程序注册为服务的几种方法(转)

    方法一: 用inf文件
    Note:**结果发现注册成的服务不能启动报错(Error 1053: The service did not respond to the start or control request in a timely fashion.),找不到原因,放弃**:

    增加一个服务:
    [Version]
    Signature="$WINDOWS NT$"
    [DefaultInstall.Services]
    AddService=myTest,,My_AddService_Name
    [My_AddService_Name]
    DisplayName=myTest
    Description=myTest服务。
    ServiceType=0x10
    StartType=2
    ErrorControl=0
    ServiceBinary=%11%myTest.exe

      保存为inetsvr.inf,然后在运行里注册该文件:
    rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 c:\path\myTestRegister.inf
      这个例子增加一个名为myTest.的服务.

    //////////////////
    几点说明:
      1,最后四项分别是
      服务类型:0x10为独立进程服务,0x20为共享进程服务(比如svchost);
      启动类型:0 系统引导时加载,1 OS初始化时加载,2 由SCM(服务控制管理器)自动启动,3 手动启动,4 禁用。
    (注意,0和1只能用于驱动程序)
      错误控制:0 忽略,1 继续并警告,2 切换到LastKnownGood的设置,3 蓝屏。
      服务程序位置:%11%表示system32目录,%10%表示系统目录(WINNT或Windows),%12%为驱动目录system32drivers。
    其他取值参见DDK。你也可以不用变量,直接使用全路径。
      这四项是必须要有的。

      2,除例子中的六个项目,还有LoadOrderGroup、Dependencies等。不常用所以不介绍了。
      3,inetsvr后面有两个逗号,因为中间省略了一个不常用的参数flags。


    删除一个服务:
    [Version]
    Signature="$WINDOWS NT$"
    [DefaultInstall.Services]
    DelService=inetsvr

      很简单,不是吗?
      当然,你也可以通过导入注册表达到目的。但inf自有其优势。

      1,导出一个系统自带服务的注册表项,你会发现其执行路径是这样的:
    "ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,
    74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,74,
    00,6c,00,6e,00,74,00,73,00,76,00,72,00,2e,00,65,00,78,00,65,00,00,00
      可读性太差。其实它就是%SystemRoot%system32 lntsvr.exe,但数据类型是REG_EXPAND_SZ。当手动导入注册表以
    增加服务时,这样定义ImagePath显然很不方便。而使用inf文件就完全没有这个问题,ServiceBinary(即ImagePath)
    自动成为REG_EXPAND_SZ。

      2,最关键的是,和用SC等工具一样,inf文件的效果是即时起效的,而导入reg后必须重启才有效。
        3,inf文件会自动为服务的注册表项添加一个Security子键,使它看起来更像系统自带的服务。
        另外,AddService和DelService以及AddReg、DelReg可以同时且重复使用。即可以同时增加和删除多个服务和注册表项。

    --------------------------------------------------------------------------------------------------------------------------------------

    方法二:用C#调用myTest.exe, 生成服务
    Note: **这个方法试验成功了,可以启动也可以停止服务(可是看不到exe的运行界面:()**

    (1).先用C#建立一个"Window服务"专案myTestService,
    在WatchFile.cs界面上拖两个控件:fileSystemWatcher1和eventLog1,
    设置fileSystemWatcher的属性-filter为"myTest.exe"及path(监控myTest.exe是否被修改),
    eventLog1的source设置为fileSystemWatcher1;

    然后点属性窗口的"加入安装程式",
    会创建一个新页面ProjectInstaller.cs,设置此页面界面上的serviceProcessInstaller1的account属性为LocalSystem,serviceInstaller1的设置是和服务相关的,如StartType设为Automatic自动运行,
    DisplayName为myTestService1是生成的服务的名子。。。

    (2).编写WatchFile.cs程式(见后面)

    (3).建置,在专案的bin\debug下得到一个myTestService.exe
    然后在.NET的命令提示字元里,进入这个专案的bin\debug,
    安装服务:installutil myTestService.exe
    卸除服务:install /u myTestService.exe(先停止服务再卸)

    也可以创建安装文件:
    加入一个安装专案TestSetup,
    点右键:加入->专案输出(选择主要输出),
    然后再点右键:检视->自定动作(按此的右键)->应用程序资料夹->加入里面的东东
    建置此专案,在TestSetup文件夹的Debug下会有安装文件,安装就可以了

     (4). 安装后,在控制面板的服务里看到服务myTestService1已经有了,
    可以启动和停止测看看exe启动没有(在进程里看),也可以查看电脑的应用程序日志文件看程式里的打印信息

    主要程式如下:
    //////////////////
    WatchFile.cs的程式: 主要是OnStart和OnStop

    ========OnStart启动服务========
    protected override void OnStart(string[] args)
    {
      try
      {
     eventLog1.WriteEntry("[myTest Info]: Start begin!");  //记录在应用程序日志里
     Process[] testService_processNames=Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName);
     System.Diagnostics.Process[] test_processNames = System.Diagnostics.Process.GetProcessesByName("myTest");

     // if there is more than one process
     if (testService_processNames.Length > 1 || test_processNames.Length >0)
     {
       eventLog1.WriteEntry("[myTest Info]: myTest is already running");
       return;
     }
     else
     {
       //在App.config里定义了filepath和filename
       System.Diagnostics.ProcessStartInfo  Info  =  new  System.Diagnostics.ProcessStartInfo();
       Info.WorkingDirectory =System.Configuration.ConfigurationSettings.AppSettings.Get("filepath");//path of exe
       Info.FileName =System.Configuration.ConfigurationSettings.AppSettings.Get("filename");//name of exe
       //Info.Arguments  =  "";
          
    //  Info.CreateNoWindow=false;
    //  Info.Verb="open";
      Info.WindowStyle=System.Diagnostics.ProcessWindowStyle.Normal;
    //  Info.UseShellExecute=true;


       //声明一个程序类
       System.Diagnostics.Process  Proc  ;

       try
       {
       Proc=System.Diagnostics.Process.Start(Info);//启动外部程序myTest.exe
       }
       catch(System.ComponentModel.Win32Exception  e)
       {
      eventLog1.WriteEntry("[myTest Info]: 系统找不到指定的程序文件。\r{0}"+ e.Message);
      return;
       }

    //  //打印出外部程序的开始执行时间
       eventLog1.WriteEntry("外部程序的开始执行时间:{0}",  Proc.StartTime);

    //
    //    //等待3秒钟
    //    Proc.WaitForExit(3000);
    //     
    //    //如果这个外部程序没有结束运行则对其强行终止
    //    if(Proc.HasExited  ==  false)
    //    {
    //     eventLog1.WriteEntry("由主程序强行终止外部程序的运行!");
    //     Proc.Kill();
    //    }
    //    else
    //    {
    //     eventLog1.WriteEntry("由外部程序正常退出!");
    //    }
    //    eventLog1.WriteEntry("外部程序的结束运行时间:{0}",  Proc.ExitTime);
    //    eventLog1.WriteEntry("外部程序在结束运行时的返回值:{0}",  Proc.ExitCode);

       }

      }
      catch(System.Exception ex)
      {
       eventLog1.WriteEntry("[myTest Info]: Start error- " +ex.Message);
       return;
      }

    }

    ========OnStop停止服务========
     protected override void OnStop()
     {
       try
       {
        eventLog1.WriteEntry("[myTest Info]: Stop Begin!");
        System.Diagnostics.Process[] Test_processNames = System.Diagnostics.Process.GetProcessesByName("myTest");
        foreach(System.Diagnostics.Process processChild in Test_processNames)
        {
         eventLog1.WriteEntry("[PBX Info]: ProcessName= " +processChild.ProcessName);
         processChild.Kill();
        }
       }
       catch(System.Exception ex)
       {
        eventLog1.WriteEntry("[myTest Info]: Stop error- "+ex.Message);
        return;
       }
      }

    ========写入txt日志文件========

      public static void WriteLog(string strLog)
      {
       string strPath;
       strPath="D:\\Test";
       strPath+=@"\mylog.tx;
       FileStream fs = new FileStream(strPath,FileMode.OpenOrCreate,FileAccess.Write);
       StreamWriter m_streamWriter = new StreamWriter(fs);
       m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
       m_streamWriter.WriteLine(strLog);                       
       m_streamWriter.Flush();
       m_streamWriter.Close();
       fs.Close();
      }

    ========App.config========

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <appSettings>
      <add key="filepath" value="D:\\myfile\\done" />
      <add key="filename" value="myTest.exe" />
     </appSettings>
    </configuration>

  • 相关阅读:
    SSIS ->> Excel Destination无法接受大于255个字符长度的字符字段(转载)
    在express站点中使用ejs模板引擎
    Kali Linux系列教程之OpenVas安装
    Kali Linux Web 渗透测试视频教程— 第二课 google hack 实战
    Kali Linux Web 渗透测试视频教程— 第四课 google hack 实战
    google hack 之 查询语法
    shellKali Linux Web 渗透测试— 初级教程(第三课)
    NODE-WEBKIT教程(12)全屏
    node-webkit教程(11)Platform Service之shell
    node-webkit教程(10)Platform Service之File dialogs
  • 原文地址:https://www.cnblogs.com/yequan/p/1446832.html
Copyright © 2011-2022 走看看