2009-09-02 113 views
26

我有一个Windows服务,用C#编写,我需要从它运行一个控制台应用程序。 控制台应用程序也用C#编写。如何从Windows Service运行控制台应用程序?

当控制台应用程序不是从Windows服务运行时,它运行良好。当它从ws运行时,它不会做任何事情,因为它应该工作10-20秒,我在调试代码中看到的是一次执行的。

我真的开始我用下面的代码控制台应用程序:

proc.Start(fullPathToConsole, args); 
proc.WaitForExit(); 

的路径,控制台是正确的,当我真的尝试从CMD或只是在资源管理器(无参数)运行它,它工作正常。但在运行服务后,我看不出任何效果。

我已经尝试去服务属性,并授予它访问桌面和运行在系统和我的用户(也在服务属性中指定)。全部保持不变。

此外:我知道服务没有用户界面,我不想要一个。我想要服务来运行控制台应用程序。不需要从它获取任何数据或使用像ui这样的控制台,只是运行它来完成它的工作。

更新I:发现,运行calc或任何其他Windows应用程序很容易。但仍然无法运行cmd或任何控制台应用程序。其实我需要在XP SP2和Windows 2003 Server上运行它。因此,无论如何不需要与Vista交互。

会很高兴有任何意见!

+0

与此应用程序有关的控制台窗口的目的是什么?也许如果我们对应用程序的概念有了一个概念,我们可以提供一个更合适的解决方案。 – BenAlabaster 2009-09-02 18:07:14

+0

其实并不重要。问题是我无法启动它。如果您知道如何使用该服务启动控制台 - 请发布代码。我需要的原因太长了。我知道当你需要一个应用程序来运行其他应用程序时,它看起来像拱门的气味,但相信我,我有理由需要这个:-) – 2009-09-02 18:12:27

+0

你需要它的理由是无关紧要的。真。微软一直对与桌面交互的服务不屑一顾,但自破解攻击发明以来,他们已决定弃用此功能并将其完全移除。你需要找出一个不同的解决方案。 – 2009-09-02 18:18:42

回答

22

从Windows Vista开始,服务无法与桌面交互。您将无法看到从服务启动的任何窗口或控制台窗口。请参阅此MSDN forum thread

在其他操作系统上,在名为“允许服务与桌面交互”的服务选项中提供了一个选项。从技术上讲,你应该为未来编程,即使你没有在Vista上使用它,也应该遵循Vista指南。

如果您仍想运行永不与桌面交互的应用程序,请尝试指定该过程以不使用该shell。

ProcessStartInfo info = new ProcessStartInfo(@"c:\myprogram.exe"); 
info.UseShellExecute = false; 
info.RedirectStandardError = true; 
info.RedirectStandardInput = true; 
info.RedirectStandardOutput = true; 
info.CreateNoWindow = true; 
info.ErrorDialog = false; 
info.WindowStyle = ProcessWindowStyle.Hidden; 

Process process = Process.Start(info); 

看看这是否有窍门。

首先通知Windows,该程序将不使用shell(在Vista中无法访问该服务)。

其次,您重定向所有控制台交互,内部流(见process.StandardInputprocess.StandardOutput

+0

我不需要看到任何东西。我所需要的 - 启动控制台应用程序,它将完成这项工作。我知道服务没有UI等问题是关于如何从服务应用程序启动控制台。 – 2009-09-02 18:18:16

+0

然后不要称之为控制台应用程序。控制台应用程序有一个UI,这是控制台。尝试将其更改为Windows应用程序,但不显示任何内容。 – 2009-09-02 18:22:50

+0

我有2个应用程序:服务和控制台应用程序。控制台应用可以完成工作,并且不会与用户进行交互。所以我写道,我不需要任何ui服务或控制台与用户交互,我需要启动控制台应用程序来完成它的工作,并需要从我的服务中完成。我说错了什么? – 2009-09-02 18:29:25

4

Windows服务没有用户界面,你可以从一个控制台应用程序的输出重定向到您的服务与this question所示的代码。

+0

我不'吨需要有一个UI或重定向的输出。我需要启动一个控制台应用程序,让它做的工作。我不'吨需要任何UI,所以它'不是出路。 – 2009-09-02 18:16:39

0

正如皮埃尔所说,没有办法为windows服务提供用户界面(或者没有简单的方法),我在这种情况下做的是在服务器上读取设置文件服务运行时间间隔,并有一个独立的应用程序,可以更改设置文件。

+0

请阅读我的意见,其他的答案,我不'吨需要服务的UI。 – 2009-09-02 18:19:33

0

您的控制台应用程序是否需要用户交互?如果是这样,这是一个严重的禁忌,你应该重新设计你的应用程序。尽管在老版本的操作系统中进行这类工作有一些窍门,但这种做法在将来会得到保证。

如果您的应用不需要用户交互,那么您的问题可能与服务运行时的用户有关。请确保您以正确的用户身份运行,或者确保您使用的用户和/或资源具有正确的权限。

如果您需要某种用户交互,则需要创建一个客户端应用程序并通过rpc,套接字或命名管道与服务和/或子应用程序进行通信。

+0

没有互动活动中所需编辑。我试过系统帐户和我的管理员帐户。我认为管理员帐户应该enuogh启动一个控制台应用程序。 – 2009-09-02 18:26:19

0

服务需要连接到服务控制管理器并在启动时提供反馈(即告诉SCM'我还活着!')。这就是为什么C#应用程序有不同的服务项目模板。你有两个选择:

  • wrapp您的SRVANY.EXE exe文件,如KB描述How To Create a User-Defined Service
  • 有你的C#应用​​程序检测时,推出的一种服务和开关控制的(如命令行PARAM。)继承自ServiceBase并正确实现服务的类。
8

我在成功之前完成了这个工作 - 我在家里有一些代码。当我今晚回到家时,我会用启动控制台应用程序的服务的工作代码更新此答案。

我以为我会从头开始尝试。以下是我写的启动控制台应用程序的一些代码。我将它安装为一个服务并运行它,它运行正常:cmd.exe启动(如任务管理器中所示)并持续10秒,直到我将它发送给exit命令。我希望这可以帮助你的情况,因为它在这里可以正常工作。

using (System.Diagnostics.Process process = new System.Diagnostics.Process()) 
    { 
     process.StartInfo = new System.Diagnostics.ProcessStartInfo(@"c:\windows\system32\cmd.exe"); 
     process.StartInfo.CreateNoWindow = true; 
     process.StartInfo.ErrorDialog = false; 
     process.StartInfo.RedirectStandardError = true; 
     process.StartInfo.RedirectStandardInput = true; 
     process.StartInfo.RedirectStandardOutput = true; 
     process.StartInfo.UseShellExecute = false; 
     process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
     process.Start(); 
     //// do some other things while you wait... 
     System.Threading.Thread.Sleep(10000); // simulate doing other things... 
     process.StandardInput.WriteLine("exit"); // tell console to exit 
     if (!process.HasExited) 
     { 
      process.WaitForExit(120000); // give 2 minutes for process to finish 
      if (!process.HasExited) 
      { 
       process.Kill(); // took too long, kill it off 
      } 
     } 
    } 
+0

那太棒了!真的不耐烦等待! :-) – 2009-09-02 18:30:36

0

我有一个Windows服务,并添加以下行来构造我的服务:

using System.Diagnostics; 
try { 
    Process p = Process.Start(@"C:\Windows\system32\calc.exe"); 
} catch { 
    Debugger.Break(); 
} 

当我试图运行此,()调用被做了的Process.Start,并没有发生异常。但是,calc.exe应用程序没有显示出来。为了使其工作,我已经在Service Control Manager中编辑了我的服务的属性,以启用与桌面的交互。完成后,Process.Start()按预期打开calc.exe。

但正如其他人所说,与桌面的互动被微软所诟病,并且基本上已在Vista中被禁用。所以即使你能在XP下运行它,我也不知道你能在Vista中运行它。

-11

在Windows服务中运行任何应用程序,例如“.exe”是很奇怪的,因为算法不是那么有效。

+1

为什么?我们已将应用程序发布为控制台应用程序和服务。例如,控制台应用程序更容易调试。 – 2011-06-11 15:20:36

+0

写作毫无意义的语句甚至更少 – LastTribunal 2015-08-06 16:06:14

+0

将如何影响算法的有效性是否有效? – 2017-11-20 11:03:00

0
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using System.ServiceProcess; 
using System.Runtime.InteropServices; 

namespace SystemControl 
{ 
    class Services 
    { 
     static string strPath = @"D:\"; 
     static void Main(string[] args) 
     { 
      string strServiceName = "WindowsService1"; 
      CreateFolderStructure(strPath); 
      string svcPath = @"D:\Applications\MSC\Agent\bin\WindowsService1.exe"; 
      if (!IsInstalled(strServiceName)) 
      { 
       InstallAndStart(strServiceName, strServiceName, svcPath + " -k runservice");     
      } 
      else 
      { 
       Console.Write(strServiceName + " already installed. Do you want to Uninstalled the Service.Y/N.?"); 
       string strKey = Console.ReadLine(); 

       if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y")|| strKey.StartsWith("Y"))) 
       { 
        StopService(strServiceName); 
        Uninstall(strServiceName); 
        ServiceLogs(strServiceName + " Uninstalled.!", strPath); 
        Console.Write(strServiceName + " Uninstalled.!"); 
        Console.Read(); 
       } 
      } 
     } 

     #region "Environment Variables" 
     public static string GetEnvironment(string name, bool ExpandVariables = true) 
     { 
      if (ExpandVariables) 
      { 
       return System.Environment.GetEnvironmentVariable(name); 
      } 
      else 
      { 
       return (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\").GetValue(name, "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames); 
      } 
     } 

     public static void SetEnvironment(string name, string value) 
     { 
      System.Environment.SetEnvironmentVariable(name, value); 
     } 
     #endregion 

     #region "ServiceCalls Native" 
     public static ServiceController[] List { get { return ServiceController.GetServices(); } } 

     public static void Start(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Start(); 
       service.WaitForStatus(ServiceControllerStatus.Running, timeout); 
      } 
      catch(Exception ex) 
      { 
       // ... 
      } 
     } 

     public static void Stop(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Stop(); 
       service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 
      } 
      catch 
      { 
       // ... 
      } 
     } 

     public static void Restart(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       int millisec1 = Environment.TickCount; 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Stop(); 
       service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 

       // count the rest of the timeout 
       int millisec2 = Environment.TickCount; 
       timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1)); 

       service.Start(); 
       service.WaitForStatus(ServiceControllerStatus.Running, timeout); 
      } 
      catch 
      { 
       // ... 
      } 
     } 

     public static bool IsInstalled(string serviceName) 
     { 
      // get list of Windows services 
      ServiceController[] services = ServiceController.GetServices(); 

      // try to find service name 
      foreach (ServiceController service in services) 
      { 
       if (service.ServiceName == serviceName) 
        return true; 
      } 
      return false; 
     } 
     #endregion 

     #region "ServiceCalls API" 
     private const int STANDARD_RIGHTS_REQUIRED = 0xF0000; 
     private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010; 

     [Flags] 
     public enum ServiceManagerRights 
     { 
      Connect = 0x0001, 
      CreateService = 0x0002, 
      EnumerateService = 0x0004, 
      Lock = 0x0008, 
      QueryLockStatus = 0x0010, 
      ModifyBootConfig = 0x0020, 
      StandardRightsRequired = 0xF0000, 
      AllAccess = (StandardRightsRequired | Connect | CreateService | 
      EnumerateService | Lock | QueryLockStatus | ModifyBootConfig) 
     } 

     [Flags] 
     public enum ServiceRights 
     { 
      QueryConfig = 0x1, 
      ChangeConfig = 0x2, 
      QueryStatus = 0x4, 
      EnumerateDependants = 0x8, 
      Start = 0x10, 
      Stop = 0x20, 
      PauseContinue = 0x40, 
      Interrogate = 0x80, 
      UserDefinedControl = 0x100, 
      Delete = 0x00010000, 
      StandardRightsRequired = 0xF0000, 
      AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig | 
      QueryStatus | EnumerateDependants | Start | Stop | PauseContinue | 
      Interrogate | UserDefinedControl) 
     } 

     public enum ServiceBootFlag 
     { 
      Start = 0x00000000, 
      SystemStart = 0x00000001, 
      AutoStart = 0x00000002, 
      DemandStart = 0x00000003, 
      Disabled = 0x00000004 
     } 

     public enum ServiceState 
     { 
      Unknown = -1, // The state cannot be (has not been) retrieved. 
      NotFound = 0, // The service is not known on the host server. 
      Stop = 1, // The service is NET stopped. 
      Run = 2, // The service is NET started. 
      Stopping = 3, 
      Starting = 4, 
     } 

     public enum ServiceControl 
     { 
      Stop = 0x00000001, 
      Pause = 0x00000002, 
      Continue = 0x00000003, 
      Interrogate = 0x00000004, 
      Shutdown = 0x00000005, 
      ParamChange = 0x00000006, 
      NetBindAdd = 0x00000007, 
      NetBindRemove = 0x00000008, 
      NetBindEnable = 0x00000009, 
      NetBindDisable = 0x0000000A 
     } 

     public enum ServiceError 
     { 
      Ignore = 0x00000000, 
      Normal = 0x00000001, 
      Severe = 0x00000002, 
      Critical = 0x00000003 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private class SERVICE_STATUS 
     { 
      public int dwServiceType = 0; 
      public ServiceState dwCurrentState = 0; 
      public int dwControlsAccepted = 0; 
      public int dwWin32ExitCode = 0; 
      public int dwServiceSpecificExitCode = 0; 
      public int dwCheckPoint = 0; 
      public int dwWaitHint = 0; 
     } 

     [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerA")] 
     private static extern IntPtr OpenSCManager(string lpMachineName, string lpDatabaseName, ServiceManagerRights dwDesiredAccess); 
     [DllImport("advapi32.dll", EntryPoint = "OpenServiceA", CharSet = CharSet.Ansi)] 
     private static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceRights dwDesiredAccess); 
     [DllImport("advapi32.dll", EntryPoint = "CreateServiceA")] 
     private static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword); 
     [DllImport("advapi32.dll")] 
     private static extern int CloseServiceHandle(IntPtr hSCObject); 
     [DllImport("advapi32.dll")] 
     private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus); 
     [DllImport("advapi32.dll", SetLastError = true)] 
     private static extern int DeleteService(IntPtr hService); 
     [DllImport("advapi32.dll")] 
     private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus); 
     [DllImport("advapi32.dll", EntryPoint = "StartServiceA")] 
     private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors); 

     /// <summary> 
     /// Takes a service name and tries to stop and then uninstall the windows serviceError 
     /// </summary> 
     /// <param name="ServiceName">The windows service name to uninstall</param> 
     public static void Uninstall(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr service = OpenService(scman, ServiceName, ServiceRights.StandardRightsRequired | ServiceRights.Stop | ServiceRights.QueryStatus); 
       if (service == IntPtr.Zero) 
       { 
        throw new ApplicationException("Service not installed."); 
       } 
       try 
       { 
        StopService(service); 
        int ret = DeleteService(service); 
        if (ret == 0) 
        { 
         int error = Marshal.GetLastWin32Error(); 
         throw new ApplicationException("Could not delete service " + error); 
        } 
       } 
       finally 
       { 
        CloseServiceHandle(service); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Accepts a service name and returns true if the service with that service name exists 
     /// </summary> 
     /// <param name="ServiceName">The service name that we will check for existence</param> 
     /// <returns>True if that service exists false otherwise</returns> 
     public static bool ServiceIsInstalled(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr service = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus); 
       if (service == IntPtr.Zero) return false; 
       CloseServiceHandle(service); 
       return true; 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Takes a service name, a service display name and the path to the service executable and installs/starts the windows service. 
     /// </summary> 
     /// <param name="ServiceName">The service name that this service will have</param> 
     /// <param name="DisplayName">The display name that this service will have</param> 
     /// <param name="FileName">The path to the executable of the service</param> 
     public static void InstallAndStart(string ServiceName, string DisplayName, 
     string FileName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect | 
      ServiceManagerRights.CreateService); 
      try 
      { 
       string strKey = string.Empty; 
       IntPtr service = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus | ServiceRights.Start); 
       if (service == IntPtr.Zero) 
       { 
        service = CreateService(scman, ServiceName, DisplayName, 
        ServiceRights.QueryStatus | ServiceRights.Start, SERVICE_WIN32_OWN_PROCESS, 
        ServiceBootFlag.AutoStart, ServiceError.Normal, FileName, null, IntPtr.Zero, 
        null, null, null); 
        ServiceLogs(ServiceName + " Installed Sucessfully.!", strPath); 
        Console.Write(ServiceName + " Installed Sucessfully.! Do you want to Start the Service.Y/N.?"); 
        strKey=Console.ReadLine(); 
       } 
       if (service == IntPtr.Zero) 
       { 
        ServiceLogs("Failed to install service.", strPath); 
        throw new ApplicationException("Failed to install service."); 
       } 
       try 
       { 
        if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y") || strKey.StartsWith("Y"))) 
        { 
         StartService(service); 
         ServiceLogs(ServiceName + " Started Sucessfully.!", strPath); 
         Console.Write(ServiceName + " Started Sucessfully.!"); 
         Console.Read(); 
        } 
       } 
       finally 
       { 
        CloseServiceHandle(service); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Takes a service name and starts it 
     /// </summary> 
     /// <param name="Name">The service name</param> 
     public static void StartService(string Name) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus | 
       ServiceRights.Start); 
       if (hService == IntPtr.Zero) 
       { 
        ServiceLogs("Could not open service.", strPath); 
        throw new ApplicationException("Could not open service."); 
       } 
       try 
       { 
        StartService(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(hService); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Stops the provided windows service 
     /// </summary> 
     /// <param name="Name">The service name that will be stopped</param> 
     public static void StopService(string Name) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus | 
       ServiceRights.Stop); 
       if (hService == IntPtr.Zero) 
       { 
        ServiceLogs("Could not open service.", strPath); 
        throw new ApplicationException("Could not open service."); 
       } 
       try 
       { 
        StopService(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(hService); 
       } 



} 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Stars the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the windows service</param> 
     private static void StartService(IntPtr hService) 
     { 
      SERVICE_STATUS status = new SERVICE_STATUS(); 
      StartService(hService, 0, 0); 
      WaitForServiceStatus(hService, ServiceState.Starting, ServiceState.Run); 
     } 

     /// <summary> 
     /// Stops the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the windows service</param> 
     private static void StopService(IntPtr hService) 
     { 
      SERVICE_STATUS status = new SERVICE_STATUS(); 
      ControlService(hService, ServiceControl.Stop, status); 
      WaitForServiceStatus(hService, ServiceState.Stopping, ServiceState.Stop); 
     } 

     /// <summary> 
     /// Takes a service name and returns the <code>ServiceState</code> of the corresponding service 
     /// </summary> 
     /// <param name="ServiceName">The service name that we will check for his <code>ServiceState</code></param> 
     /// <returns>The ServiceState of the service we wanted to check</returns> 
     public static ServiceState GetServiceStatus(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus); 
       if (hService == IntPtr.Zero) 
       { 
        return ServiceState.NotFound; 
       } 
       try 
       { 
        return GetServiceStatus(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(scman); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Gets the service state by using the handle of the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the service</param> 
     /// <returns>The <code>ServiceState</code> of the service</returns> 
     private static ServiceState GetServiceStatus(IntPtr hService) 
     { 
      SERVICE_STATUS ssStatus = new SERVICE_STATUS(); 
      if (QueryServiceStatus(hService, ssStatus) == 0) 
      { 
       ServiceLogs("Failed to query service status.", strPath); 
       throw new ApplicationException("Failed to query service status."); 
      } 
      return ssStatus.dwCurrentState; 
     } 

     /// <summary> 
     /// Returns true when the service status has been changes from wait status to desired status 
     /// ,this method waits around 10 seconds for this operation. 
     /// </summary> 
     /// <param name="hService">The handle to the service</param> 
     /// <param name="WaitStatus">The current state of the service</param> 
     /// <param name="DesiredStatus">The desired state of the service</param> 
     /// <returns>bool if the service has successfully changed states within the allowed timeline</returns> 
     private static bool WaitForServiceStatus(IntPtr hService, ServiceState 
     WaitStatus, ServiceState DesiredStatus) 
     { 
      SERVICE_STATUS ssStatus = new SERVICE_STATUS(); 
      int dwOldCheckPoint; 
      int dwStartTickCount; 

      QueryServiceStatus(hService, ssStatus); 
      if (ssStatus.dwCurrentState == DesiredStatus) return true; 
      dwStartTickCount = Environment.TickCount; 
      dwOldCheckPoint = ssStatus.dwCheckPoint; 

      while (ssStatus.dwCurrentState == WaitStatus) 
      { 
       // Do not wait longer than the wait hint. A good interval is 
       // one tenth the wait hint, but no less than 1 second and no 
       // more than 10 seconds. 

       int dwWaitTime = ssStatus.dwWaitHint/10; 

       if (dwWaitTime < 1000) dwWaitTime = 1000; 
       else if (dwWaitTime > 10000) dwWaitTime = 10000; 

       System.Threading.Thread.Sleep(dwWaitTime); 

       // Check the status again. 

       if (QueryServiceStatus(hService, ssStatus) == 0) break; 

       if (ssStatus.dwCheckPoint > dwOldCheckPoint) 
       { 
        // The service is making progress. 
        dwStartTickCount = Environment.TickCount; 
        dwOldCheckPoint = ssStatus.dwCheckPoint; 
       } 
       else 
       { 
        if (Environment.TickCount - dwStartTickCount > ssStatus.dwWaitHint) 
        { 
         // No progress made within the wait hint 
         break; 
        } 
       } 
      } 
      return (ssStatus.dwCurrentState == DesiredStatus); 
     } 

     /// <summary> 
     /// Opens the service manager 
     /// </summary> 
     /// <param name="Rights">The service manager rights</param> 
     /// <returns>the handle to the service manager</returns> 
     private static IntPtr OpenSCManager(ServiceManagerRights Rights) 
     { 
      IntPtr scman = OpenSCManager(null, null, Rights); 
      if (scman == IntPtr.Zero) 
      { 
       try 
       { 
        throw new ApplicationException("Could not connect to service control manager."); 
       } 
       catch (Exception ex) 
       { 
       } 
      } 
      return scman; 
     } 

     #endregion 

     #region"CreateFolderStructure" 
     private static void CreateFolderStructure(string path) 
     { 
      if(!System.IO.Directory.Exists(path+"Applications")) 
       System.IO.Directory.CreateDirectory(path+ "Applications"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent\\bin")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent\\bin"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\AgentService")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\AgentService"); 

      string fullPath = System.IO.Path.GetFullPath("MSCService"); 
      if (System.IO.Directory.Exists(fullPath)) 
      { 
       foreach (string strFile in System.IO.Directory.GetFiles(fullPath)) 
       { 
        if (System.IO.File.Exists(strFile)) 
        { 
         String[] strArr = strFile.Split('\\'); 
         System.IO.File.Copy(strFile, path + "Applications\\MSC\\Agent\\bin\\"+ strArr[strArr.Count()-1], true); 
        } 
       } 
      }    
     } 
     #endregion 

     private static void ServiceLogs(string strLogInfo, string path) 
     { 
      string filePath = path + "Applications\\MSC\\AgentService\\ServiceLogs.txt";    
      System.IO.File.AppendAllLines(filePath, (strLogInfo + "--" + DateTime.Now.ToString()).ToString().Split('|')); 
     } 
    } 
} 
+0

请尝试添加有用的评论与您的​​代码来描述它在做什么以及它如何解决问题,而不是只发布代码本身。 – 2015-08-30 01:36:54

+1

尽管此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文可提高其长期价值。 – JAL 2015-09-01 19:14:41

相关问题