熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

高手進階:給WINDOWS服務加上描述

2013-11-13 10:19:43  來源: .NET編程 
    當我們創建一個WINDOWS服務後卻發覺我們所創建的服務沒有相關的描述(你可以打開服務管理器程序查看)而SystemServiceProcessServiceBase這些相關的類都沒有提供這方面的信息同樣如果我們需要給我們的服務加上恰當的描述我們也只能通過非托管代碼來處理

  

  using System;
using SystemRuntimeInteropServices;

  namespace FileWatchService
{
 public class modAPI
 {
  [DllImport(advapidll)]
  public static extern int LockServiceDatabase(int hSCManager);
 
  [DllImport(advapidll)]
  public static extern bool UnlockServiceDatabase(int hSCManager);
 
  [DllImport(kerneldll)]
  public static extern void CopyMemory(IntPtr pDst SC_ACTION[] pSrcint ByteLen);
 
  [DllImport(advapidll)]
  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(advapidll)]
  public static extern bool ChangeServiceConfigA(
   int hService InfoLevel dwInfoLevel
   [MarshalAs(UnmanagedTypeStruct)] ref SERVICE_DESCRIPTION lpInfo);

  [DllImport(advapidll)]
  public static extern bool ChangeServiceConfigA(
   int hService InfoLevel dwInfoLevel
   [MarshalAs(UnmanagedTypeStruct)] ref SERVICE_FAILURE_ACTIONS lpInfo);

  [DllImport(advapidll)]
  public static extern int OpenServiceA(
   int hSCManager string lpServiceName ACCESS_TYPE dwDesiredAccess);

  [DllImport(advapidll)]
  public static extern int OpenSCManagerA(
   string lpMachineName string lpDatabaseName ServiceControlManagerType dwDesiredAccess);

  [DllImport(advapidll)]
  public static extern bool CloseServiceHandle(
   int hSCObject);

  [DllImport(advapidll)]
  public static extern bool QueryServiceConfigA(
   int hService [MarshalAs(UnmanagedTypeStruct)]
ref QUERY_SERVICE_CONFIG lpServiceConfig int cbBufSize
   int pcbBytesNeeded);
  [DllImport(advapidll)]
  public static extern int StartService(int SVHANDLEint dwNumServiceArgsstring lpServiceArgVectors);

  public const int STANDARD_RIGHTS_REQUIRED = xF;
  public const int GENERIC_READ = ;
  public const int ERROR_INSUFFICIENT_BUFFER = ;
  public const int SERVICE_NO_CHANGE = ;
  //public const int SERVICE_NO_CHANGE = xFFFF;

  public enum ServiceType
  {
   SERVICE_KERNEL_DRIVER = x
   SERVICE_FILE_SYSTEM_DRIVER = x
   SERVICE_WIN_OWN_PROCESS = x
   SERVICE_WIN_SHARE_PROCESS = x
   SERVICE_INTERACTIVE_PROCESS = x
   SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE
  }

  public enum ServiceStartType:int
  {
   SERVICE_BOOT_START = x
   SERVICE_SYSTEM_START = x
   SERVICE_AUTO_START = x
   SERVICE_DEMAND_START = x
   SERVICE_DISABLED = x
   SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE
  }

  public enum ServiceErrorControl:int
  {
   SERVICE_ERROR_IGNORE = x
   SERVICE_ERROR_NORMAL = x
   SERVICE_ERROR_SEVERE = x
   SERVICE_ERROR_CRITICAL = x
   msidbServiceInstallErrorControlVital = x
   SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE
  }

  public enum ServiceStateRequest:int
  {
   SERVICE_ACTIVE = x
   SERVICE_INACTIVE = x
   SERVICE_STATE_ALL = (SERVICE_ACTIVE + SERVICE_INACTIVE)
  }

  public enum ServiceControlType:int
  {
   SERVICE_CONTROL_STOP = x
   SERVICE_CONTROL_PAUSE = x
   SERVICE_CONTROL_CONTINUE = x
   SERVICE_CONTROL_INTERROGATE = x
   SERVICE_CONTROL_SHUTDOWN = x
   SERVICE_CONTROL_PARAMCHANGE = x
   SERVICE_CONTROL_NETBINDADD = x
   SERVICE_CONTROL_NETBINDREMOVE = x
   SERVICE_CONTROL_NETBINDENABLE = x
   SERVICE_CONTROL_NETBINDDISABLE = xA
   SERVICE_CONTROL_DEVICEEVENT = xB
   SERVICE_CONTROL_HARDWAREPROFILECHANGE = xC
   SERVICE_CONTROL_POWEREVENT = xD
   SERVICE_CONTROL_SESSIONCHANGE = xE
  }

  public enum ServiceState:int
  {
   SERVICE_STOPPED = x
   SERVICE_START_PENDING = x
   SERVICE_STOP_PENDING = x
   SERVICE_RUNNING = x
   SERVICE_CONTINUE_PENDING = x
   SERVICE_PAUSE_PENDING = x
   SERVICE_PAUSED = x
  }

  public enum ServiceControlAccepted:int
  {
   SERVICE_ACCEPT_STOP = x
   SERVICE_ACCEPT_PAUSE_CONTINUE = x
   SERVICE_ACCEPT_SHUTDOWN = x
   SERVICE_ACCEPT_PARAMCHANGE = x
   SERVICE_ACCEPT_NETBINDCHANGE = x
   SERVICE_ACCEPT_HARDWAREPROFILECHANGE = x
   SERVICE_ACCEPT_POWEREVENT = x
   SERVICE_ACCEPT_SESSIONCHANGE = x
  }

  public enum ServiceControlManagerType:int
  {
   SC_MANAGER_CONNECT = x
   SC_MANAGER_CREATE_SERVICE = x
   SC_MANAGER_ENUMERATE_SERVICE = x
   SC_MANAGER_LOCK = x
   SC_MANAGER_QUERY_LOCK_STATUS = x
   SC_MANAGER_MODIFY_BOOT_CONFIG = x
   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 = x
   SERVICE_CHANGE_CONFIG = x
   SERVICE_QUERY_STATUS = x
   SERVICE_ENUMERATE_DEPENDENTS = x
   SERVICE_START = x
   SERVICE_STOP = x
   SERVICE_PAUSE_CONTINUE = x
   SERVICE_INTERROGATE = x
   SERVICE_USER_DEFINED_CONTROL = x
   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(LayoutKindSequential)]
   public struct SERVICE_STATUS
  {
   public int dwServiceType;
   public int dwCurrentState;
   public int dwControlsAccepted;
   public int dwWinExitCode;
   public int dwServiceSpecificExitCode;
   public int dwCheckPoint;
   public int dwWaitHint;
  }
 
  [StructLayout(LayoutKindSequential)]
   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 =
   SC_ACTION_RESTART =
   SC_ACTION_REBOOT =
   SC_ACTION_RUN_COMMAND =
  }

  [StructLayout(LayoutKindSequential)]
   public struct SC_ACTION
  {
   public SC_ACTION_TYPE SCActionType;
   public int Delay;
  }

  public enum InfoLevel:int
  {
   SERVICE_CONFIG_DESCRIPTION =
   SERVICE_CONFIG_FAILURE_ACTIONS =
  }

  [StructLayout(LayoutKindSequential)]
   public struct SERVICE_DESCRIPTION
  {
   public string lpDescription;
  }

  [StructLayout(LayoutKindSequential)]
   public struct SERVICE_FAILURE_ACTIONS
  {
   public int dwResetPeriod;
   public string lpRebootMsg;
   public string lpCommand;
   public int cActions;
   public int lpsaActions;
  }
 }
}


  當我們給服務增加安裝包時我們可以在ProjectInstaller裡加上我們修改服務描述的代碼


  private void InitializeComponent()
  {

  //這裡要增加代碼
thisAfterInstall += new SystemConfigurationInstallInstallEventHandler(thisProjectInstaller_AfterInstall);

  }

  private void ProjectInstaller_AfterInstall(object senderSystemConfigurationInstallInstallEventArgs e)
  {

  int iSCManagerHandle = ;
   int iSCManagerLockHandle = ;
   int iServiceHandle = ;
   bool bChangeServiceConfig = false;
   bool bChangeServiceConfig = false;
   modAPISERVICE_DESCRIPTION ServiceDescription;
   modAPISERVICE_FAILURE_ACTIONS ServiceFailureActions;
   modAPISC_ACTION[] ScActions = new modAPISC_ACTION[];

  bool bCloseService = false;
   bool bUnlockSCManager = false;
   bool bCloseSCManager = false;

  IntPtr iScActionsPointer = new IntPtr();

  try
   {
    //打開服務控制台
    iSCManagerHandle = modAPIOpenSCManagerA(null null
     modAPIServiceControlManagerTypeSC_MANAGER_ALL_ACCESS);

    if (iSCManagerHandle < )
    {
     throw new Exception(不能打開服務管理器);
    }

    iSCManagerLockHandle = modAPILockServiceDatabase(iSCManagerHandle);

    if (iSCManagerLockHandle < )
    {
     throw new Exception(不能鎖定服務管理器);
    }

  //服務名
    iServiceHandle = modAPIOpenServiceA(iSCManagerHandle JadeWatchService
     modAPIACCESS_TYPESERVICE_ALL_ACCESS);

    if (iServiceHandle < )
    {
     throw new Exception(不能打開服務進行修改);
    }
 
  
    bChangeServiceConfig = modAPIChangeServiceConfigA(iServiceHandle
     modAPIServiceTypeSERVICE_WIN_OWN_PROCESS | modAPIServiceTypeSERVICE_INTERACTIVE_PROCESS
     modAPISERVICE_NO_CHANGE modAPISERVICE_NO_CHANGE null null
     null null null null);

    if (bChangeServiceConfig==false)
    {
     throw new Exception(不能改變服務設置);
    }

    ServiceDescriptionlpDescription = 青鳥文件監控服務如果停止該服務數據將不能正常進行備份!;

  bChangeServiceConfig = modAPIChangeServiceConfigA(iServiceHandle
     modAPIInfoLevelSERVICE_CONFIG_DESCRIPTIONref ServiceDescription);

    if (bChangeServiceConfig==false)
    {
     throw new Exception(不能進行服務描述更改);
    } 

    ServiceFailureActionsdwResetPeriod = ;
    ServiceFailureActionslpRebootMsg = 服務啟動失敗! 重啟中;
    // ServiceFailureActionslpCommand = SomeCommandexe Param Param;
    ServiceFailureActionslpCommand = ;
    ServiceFailureActionscActions = ScActionsLength;

  //故障恢復設置這裡沒有設置
    ScActions[]Delay = ;
    ScActions[]SCActionType = modAPISC_ACTION_TYPESC_ACTION_NONE; //不要對失敗操作做任何處理如果重啟服務等
    ScActions[]Delay = ;
    ScActions[]SCActionType = modAPISC_ACTION_TYPESC_ACTION_NONE;
    ScActions[]Delay = ;
    ScActions[]SCActionType = modAPISC_ACTION_TYPESC_ACTION_NONE;

    iScActionsPointer = MarshalAllocHGlobal(MarshalSizeOf(new modAPISC_ACTION()) * );

    modAPICopyMemory(iScActionsPointer ScActions MarshalSizeOf(new modAPISC_ACTION()) * );


  

  ServiceFailureActionslpsaActions = iScActionsPointerToInt();

    bChangeServiceConfig = modAPIChangeServiceConfigA(iServiceHandle
     modAPIInfoLevelSERVICE_CONFIG_FAILURE_ACTIONSref ServiceFailureActions);

    if (bChangeServiceConfig==false)
    {
     throw new Exception(不能設置服務的故障恢復設置);
    }
   
   }
   catch(Exception ex)
   {
   
    throw new Exception(exMessage);
   }
   finally
   {
   
    MarshalFreeHGlobal(iScActionsPointer);

  if (iServiceHandle > )
    {
     bCloseService = modAPICloseServiceHandle(iServiceHandle);
    }

  if (iSCManagerLockHandle > )
    {
     bUnlockSCManager = modAPIUnlockServiceDatabase(iSCManagerLockHandle);
    }

  if (iSCManagerHandle != )
    {
     bCloseSCManager = modAPICloseServiceHandle(iSCManagerHandle);
    }
   }
  
  }

  在安裝完成後我們對服務進行這裡可以修改的內容包括服務的描述服務的故障處理等

  如果你在安裝時需要對服務進行自動處於運行狀態或卸載時需要自動將服務也卸載你只要注冊

  thisbeforeuninstall+=new InstallEventHandler(ProjectInstaller_BeforeUninstall);
   thisCommitted+=new InstallEventHandler(ProjectInstaller_Committed);

  這二個事件

  committed事件在這裡可以將安裝的服務進行調整到運行狀態

  beforeuninstall事件您可以在這裡將服務自動卸載掉


From:http://tw.wingwit.com/Article/program/net/201311/13252.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.