动网论坛,站长建站首选,国内使用量最多的论坛软件 动网论坛官方技术讨论区 站长工具 申请属于您自己的免费论坛
首页 | 新闻资讯 | 网站运营 | 网络编程 | 数据库 | 服务器 | 网页设计 | 图像媒体 | 网络应用 | 搜索优化 | 资源下载 | 动网主机 | DVBOX
    本站内  互联网 ASP论坛  ASP.Net论坛  PHP论坛
   .Net → 阅读文章

 给WINDOWS的服务加上描述

作者来源: 
阅读 数 172 人次 , 2006-4-25 14:56:00 


  当我们创建一个WINDOWS服务后,却发觉我们所创建的服务没有相关的描述。(你可以打开服务管理器程序查看)。而System.ServiceProcess.ServiceBase这些相关的类都没有提供这方面的信息。同样如果我们需要给我们的服务加上恰当的描述,我们也只能通过非托管代码来处理。 

  using System;

  using System.Runtime.InteropServices;  

  namespace FileWatchService

  {

   public class modAPI

   {

   [DllImport("advapi32.dll")]

   public static extern int LockServiceDatabase(int hSCManager);  

   [DllImport("advapi32.dll")]

   public static extern bool UnlockServiceDatabase(int hSCManager);  

   [DllImport("kernel32.dll")]

   public static extern void CopyMemory(IntPtr pDst, SC_ACTION[] pSrc,int ByteLen);

   [DllImport("advapi32.dll")]

   public static extern bool ChangeServiceConfigA(

   int hService, ServiceType dwServiceType, int dwStartType,

   int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup,

   int lpdwTagId, string lpDependencies, string lpServiceStartName,

   string lpPassword, string lpDisplayName);  

   [DllImport("advapi32.dll")]

   public static extern bool ChangeServiceConfig2A(

   int hService, InfoLevel dwInfoLevel,

   [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);  

   [DllImport("advapi32.dll")]

   public static extern bool ChangeServiceConfig2A(

   int hService, InfoLevel dwInfoLevel,

   [MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo);  

   [DllImport("advapi32.dll")]

   public static extern int OpenServiceA(

   int hSCManager, string lpServiceName, ACCESS_TYPE dwDesiredAccess);  

   [DllImport("advapi32.dll")]

   public static extern int OpenSCManagerA(

   string lpMachineName, string lpDatabaseName, ServiceControlManagerType dwDesiredAccess);  

   [DllImport("advapi32.dll")]

   public static extern bool CloseServiceHandle(

   int hSCObject);  

   [DllImport("advapi32.dll")]

   public static extern bool QueryServiceConfigA(

   int hService, [MarshalAs(UnmanagedType.Struct)] ref QUERY_SERVICE_CONFIG lpServiceConfig, int cbBufSize,

   int pcbBytesNeeded);

   [DllImport("advapi32.dll")]

   public static extern int StartService(int SVHANDLE,int dwNumServiceArgs,string lpServiceArgVectors);  

   public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;

   public const int GENERIC_READ = -2147483648;

   public const int ERROR_INSUFFICIENT_BUFFER = 122;

   public const int SERVICE_NO_CHANGE = -1;

   //public const int SERVICE_NO_CHANGE = 0xFFFF;  

   public enum ServiceType

   {

   SERVICE_KERNEL_DRIVER = 0x1,

   SERVICE_FILE_SYSTEM_DRIVER = 0x2,

   SERVICE_WIN32_OWN_PROCESS = 0x10,

   SERVICE_WIN32_SHARE_PROCESS = 0x20,

   SERVICE_INTERACTIVE_PROCESS = 0x100,

   SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE

   }  

   public enum ServiceStartType:int

   {

   SERVICE_BOOT_START = 0x0,

   SERVICE_SYSTEM_START = 0x1,

   SERVICE_AUTO_START = 0x2,

   SERVICE_DEMAND_START = 0x3,

   SERVICE_DISABLED = 0x4,

   SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE

   }  

   public enum ServiceErrorControl:int

   {

   SERVICE_ERROR_IGNORE = 0x0,

   SERVICE_ERROR_NORMAL = 0x1,

   SERVICE_ERROR_SEVERE = 0x2,

   SERVICE_ERROR_CRITICAL = 0x3,

   msidbServiceInstallErrorControlVital = 0x8000,

   SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE

   }  

   public enum ServiceStateRequest:int

   {

   SERVICE_ACTIVE = 0x1,

   SERVICE_INACTIVE = 0x2,

   SERVICE_STATE_ALL = (SERVICE_ACTIVE + SERVICE_INACTIVE)

   }  

   public enum ServiceControlType:int

   {

   SERVICE_CONTROL_STOP = 0x1,

   SERVICE_CONTROL_PAUSE = 0x2,

   SERVICE_CONTROL_CONTINUE = 0x3,

   SERVICE_CONTROL_INTERROGATE = 0x4,

   SERVICE_CONTROL_SHUTDOWN = 0x5,

   SERVICE_CONTROL_PARAMCHANGE = 0x6,

   SERVICE_CONTROL_NETBINDADD = 0x7,

   SERVICE_CONTROL_NETBINDREMOVE = 0x8,

   SERVICE_CONTROL_NETBINDENABLE = 0x9,

   SERVICE_CONTROL_NETBINDDISABLE = 0xA,

   SERVICE_CONTROL_DEVICEEVENT = 0xB,

   SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC,

   SERVICE_CONTROL_POWEREVENT = 0xD,

   SERVICE_CONTROL_SESSIONCHANGE = 0xE,

   }  

   public enum ServiceState:int

   {

   SERVICE_STOPPED = 0x1,

   SERVICE_START_PENDING = 0x2,

   SERVICE_STOP_PENDING = 0x3,

   SERVICE_RUNNING = 0x4,

   SERVICE_CONTINUE_PENDING = 0x5,

   SERVICE_PAUSE_PENDING = 0x6,

   SERVICE_PAUSED = 0x7,

   }  

   public enum ServiceControlAccepted:int

   {

   SERVICE_ACCEPT_STOP = 0x1,

   SERVICE_ACCEPT_PAUSE_CONTINUE = 0x2,

   SERVICE_ACCEPT_SHUTDOWN = 0x4,

   SERVICE_ACCEPT_PARAMCHANGE = 0x8,

   SERVICE_ACCEPT_NETBINDCHANGE = 0x10,

   SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x20,

   SERVICE_ACCEPT_POWEREVENT = 0x40,

   SERVICE_ACCEPT_SESSIONCHANGE = 0x80

   }  

   public enum ServiceControlManagerType:int

   {

   SC_MANAGER_CONNECT = 0x1,

   SC_MANAGER_CREATE_SERVICE = 0x2,

   SC_MANAGER_ENUMERATE_SERVICE = 0x4,

   SC_MANAGER_LOCK = 0x8,

   SC_MANAGER_QUERY_LOCK_STATUS = 0x10,

   SC_MANAGER_MODIFY_BOOT_CONFIG = 0x20,

   SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SC_MANAGER_CONNECT + SC_MANAGER_CREATE_SERVICE + SC_MANAGER_ENUMERATE_SERVICE + SC_MANAGER_LOCK + SC_MANAGER_QUERY_LOCK_STATUS + SC_MANAGER_MODIFY_BOOT_CONFIG

   }  

   public enum ACCESS_TYPE:int

   {

   SERVICE_QUERY_CONFIG = 0x1,

   SERVICE_CHANGE_CONFIG = 0x2,

   SERVICE_QUERY_STATUS = 0x4,

   SERVICE_ENUMERATE_DEPENDENTS = 0x8,

   SERVICE_START = 0x10,

   SERVICE_STOP = 0x20,

   SERVICE_PAUSE_CONTINUE = 0x40,

   SERVICE_INTERROGATE = 0x80,

   SERVICE_USER_DEFINED_CONTROL = 0x100,

   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

   }  

   [StructLayout(LayoutKind.Sequential)]

   public struct SERVICE_STATUS

   {

   public int dwServiceType;

   public int dwCurrentState;

   public int dwControlsAccepted;

   public int dwWin32ExitCode;

   public int dwServiceSpecificExitCode;

   public int dwCheckPoint;

   public int dwWaitHint;

   }  

   [StructLayout(LayoutKind.Sequential)]

   public struct QUERY_SERVICE_CONFIG

   {

   public int dwServiceType;

   public int dwStartType;

   public int dwErrorControl;

   public string lpBinaryPathName;

   public string lpLoadOrderGroup;

   public int dwTagId;

   public string lpDependencies;

   public string lpServiceStartName;

   public string lpDisplayName;

   }  

   public enum SC_ACTION_TYPE:int

   {

   SC_ACTION_NONE = 0,

   SC_ACTION_RESTART = 1,

   SC_ACTION_REBOOT = 2,

   SC_ACTION_RUN_COMMAND = 3,

   }  

   [StructLayout(LayoutKind.Sequential)]

   public struct SC_ACTION

   {

   public SC_ACTION_TYPE SCActionType;

   public int Delay;

   }  

   public enum InfoLevel:int

   {

   SERVICE_CONFIG_DESCRIPTION = 1,

   SERVICE_CONFIG_FAILURE_ACTIONS = 2

   }  

   [StructLayout(LayoutKind.Sequential)]

   public struct SERVICE_DESCRIPTION

   {

   public string lpDescription;

   }  

   [StructLayout(LayoutKind.Sequential)]

   public struct SERVICE_FAILURE_ACTIONS

   {

   public int dwResetPeriod;

   public string lpRebootMsg;

   public string lpCommand;

   public int cActions;

   public int lpsaActions;

   }

   }

  }
  

  当我们给服务增加安装包时,我们可以在ProjectInstaller里加上我们修改服务描述的代码

  private void InitializeComponent()

   {  

  //这里要增加代码

  this.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.ProjectInstaller_AfterInstall);  

  }  

  private void ProjectInstaller_AfterInstall(object sender,System.Configuration.Install.InstallEventArgs e)

   {  

   int iSCManagerHandle = 0;

   int iSCManagerLockHandle = 0;

   int iServiceHandle = 0;

   bool bChangeServiceConfig = false;

   bool bChangeServiceConfig2 = false;

   modAPI.SERVICE_DESCRIPTION ServiceDescription;

   modAPI.SERVICE_FAILURE_ACTIONS ServiceFailureActions;

   modAPI.SC_ACTION[] ScActions = new modAPI.SC_ACTION[3];  

   bool bCloseService = false;

   bool bUnlockSCManager = false;

   bool bCloseSCManager = false;  

   IntPtr iScActionsPointer = new IntPtr();  

   try

   {

   //打开服务控制台

   iSCManagerHandle = modAPI.OpenSCManagerA(null, null,

   modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS);  

   if (iSCManagerHandle < 1)

   {

   throw new Exception("不能打开服务管理器.");

   }  

   iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle);  

   if (iSCManagerLockHandle < 1)

   {

   throw new Exception("不能锁定服务管理器.");

   }  

   //服务名

   iServiceHandle = modAPI.OpenServiceA(iSCManagerHandle, "JadeWatchService",

   modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS);  

   if (iServiceHandle < 1)

   {

   throw new Exception("不能打开服务进行修改.");

   }

   bChangeServiceConfig = modAPI.ChangeServiceConfigA(iServiceHandle,

   modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS   modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS,

   modAPI.SERVICE_NO_CHANGE, modAPI.SERVICE_NO_CHANGE, null, null,

   0, null, null, null, null);  

   if (bChangeServiceConfig==false)

   {

   throw new Exception("不能改变服务设置.");

   }

  ServiceDescription.lpDescription = "青鸟文件监控服务,如果停止该服务,数据将不能正常进行备份!";  

  bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,

  modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION,ref ServiceDescription);

   if (bChangeServiceConfig2==false)

   {

   throw new Exception("不能进行服务描述更改.");

   }
  

   ServiceFailureActions.dwResetPeriod = 600;

   ServiceFailureActions.lpRebootMsg = "服务启动失败! 重启中...";

   // ServiceFailureActions.lpCommand = "SomeCommand.exe Param1 Param2";

   ServiceFailureActions.lpCommand = "";

   ServiceFailureActions.cActions = ScActions.Length;  

   //故障恢复设置,这里没有设置

   ScActions[0].Delay = 20000;

   ScActions[0].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE; //不要对失败操作做任何处理,如果重启服务等

   ScActions[1].Delay = 20000;

   ScActions[1].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE;

   ScActions[2].Delay = 20000;

   ScActions[2].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_NONE;

   iScActionsPointer = Marshal.AllocHGlobal(Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);

   modAPI.CopyMemory(iScActionsPointer, ScActions, Marshal.SizeOf(new modAPI.SC_ACTION()) * 3); 

   ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32();  

   bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,

   modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS,ref ServiceFailureActions);

   if (bChangeServiceConfig2==false)

   {

   throw new Exception("不能设置服务的故障恢复设置.");

   }

  

   }

   catch(Exception ex)

   {  

   throw new Exception(ex.Message);

   }

   finally

   {  

   Marshal.FreeHGlobal(iScActionsPointer);  

   if (iServiceHandle > 0)

   {

   bCloseService = modAPI.CloseServiceHandle(iServiceHandle);

   }  

   if (iSCManagerLockHandle > 0)

   {

   bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle);

   }

   if (iSCManagerHandle != 0)

   {

   bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle);

   }

   }  

   }



  在安装完成后,我们对服务进行。这里可以修改的内容包括服务的描述,服务的故障处理等. 

  如果你在安装时,需要对服务进行自动处于运行状态,或卸载时需要自动将服务也卸载,你只要注册  

  this.BeforeUninstall+=new InstallEventHandler(ProjectInstaller_BeforeUninstall);

  this.Committed+=new InstallEventHandler(ProjectInstaller_Committed);  

  这二个事件  

  Committed事件,在这里可以将安装的服务进行调整到运行状态  

  BeforeUninstall事件,您可以在这里将服务自动卸载掉
  
 本文TagsWindows  
 收藏本文  打印本文  论坛讨论  关闭窗口
· 上一篇:C++/CLI思辨录之内部指针的两面性
· 下一篇:Visual C++.NET GDI+编程基础
· 用VB.NET设计各种形状的窗体界面
· JRun 2.3.x 范例文件暴露站点安全信息
· ASP.NET中Cookie编程的基础知识(5)
· 用c#写的smtp邮件发送类
· ASP.NET无法调试问题剖析


关于本站 | 联系我们 | 业务合作 | 客户案例 | 诚聘英才 | 广告合作 | 收藏本站
海口动网先锋网络科技有限公司版权所有
Copyright © 2000 - 2006 Cndw.Com
中华人民共和国电信与信息服务业务经营许可证编号 琼 ICP 020077