2009-09-02 21 views
26

Ho un servizio di Windows, scritto in C# e ho bisogno di eseguire un'applicazione di console da esso. Applicazione console scritta anche in C#.Come eseguire l'applicazione console dal servizio Windows?

L'applicazione della console funziona correttamente quando non viene eseguita dal servizio Windows. Quando viene eseguito da ws, non fa nulla e dovrebbe funzionare per 10-20 secondi che vedo nel codice di debug che viene eseguito contemporaneamente.

I`m iniziare la mia console app con il seguente codice:

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

il percorso per console è giusto e quando `m cercando di eseguirlo dal cmd o semplicemente in explorer (senza args) è funziona bene. Ma dopo aver corso con il servizio non vedo alcun effetto.

Ho già provato ad accedere alle proprietà del servizio e gli ho dato accesso al desktop ed eseguito sia con il sistema che con il mio utente (specificato anche nelle proprietà del servizio). Tutto rimane uguale.

AGGIUNTA: So che il servizio non ha ui e non ne voglio uno. Voglio che il servizio esegua l'applicazione della console. Non c'è bisogno di ottenere alcun dato da esso o utilizzare questa console come ui, basta eseguirlo per fare il suo lavoro.

AGGIORNAMENTO I: è stato rilevato che eseguire calc o qualsiasi altra applicazione di Windows è semplice. Ma non è ancora possibile eseguire cmd o qualsiasi app per console. In realtà ho bisogno di eseguirlo su XP SP2 e Windows 2003 Server. Quindi non c'è bisogno di interagire con Vista in ogni caso.

Sarei felice di commenti!

+0

Qual è lo scopo della finestra della console in relazione a questa applicazione? Forse se avessimo un'idea del concetto di applicazione potremmo fornire una soluzione più appropriata. – BenAlabaster

+0

in realtà non importa. Il problema è che non posso lanciarlo. Se sai come avviare la console con il servizio, inserisci il codice. I motivi per cui ho bisogno sono troppo lunghi. So che quando hai bisogno di un'app per eseguirne altre e quest'altra fa qualcos'altro sembra odore d'arco, ma credimi, ho dei motivi per averne bisogno :-) –

+0

I tuoi motivi per averne bisogno sono irrilevanti. Veramente. Microsoft ha sempre disapprovato i servizi che interagiscono con il desktop, ma da quando è stato inventato l'attacco in frantumi, hanno deciso di deprecare l'abilità e rimuoverla completamente.Dovrai trovare una soluzione diversa. –

risposta

22

A partire da Windows Vista, un servizio non può interagire con il desktop. Non sarà possibile visualizzare finestre o finestre della console avviate da un servizio. Vedi questo MSDN forum thread.

Su altro sistema operativo, è disponibile un'opzione disponibile nell'opzione di servizio denominata "Consenti al servizio di interagire con il desktop". Tecnicamente, dovresti programmare per il futuro e seguire le linee guida di Vista anche se non lo usi su Vista.

Se si desidera eseguire un'applicazione che non interagisce mai con il desktop, provare a specificare il processo per non utilizzare la 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); 

Vedere se questo è il trucco.

Prima si informa Windows che il programma non utilizzerà la shell (che è inaccessibile in Vista al servizio).

In secondo luogo, si reindirizza tutte le console di interazione di flusso interno (vedi process.StandardInput e process.StandardOutput. Servizi

+0

Non ho bisogno di vedere nulla. Tutto ciò di cui ho bisogno: avvia l'app della console e svolgerà il lavoro. So che il servizio non ha ui ecc. La domanda è su come avviare la console dall'app di servizio. –

+0

Quindi non chiamarlo app per console. Un'app della console ha un'interfaccia utente, che è la console. Prova a cambiarlo in un'applicazione Windows, ma questo non mostra nulla. –

+0

Ho 2 app: app di servizio e console. L'app della console funziona e non ha alcuna interazione con l'utente. Così ho scritto che non ho bisogno di alcun interfaccia utente per il servizio o che la console interagisca con l'utente, ho bisogno di avviare l'app della console per fare il suo lavoro e devo farlo dal mio servizio. Cosa ho detto di sbagliato? –

4

di Windows non hanno interfacce utente. È possibile reindirizzare l'output di una console app per il vostro servizio con il codice riportato in this question.

+0

Non ho bisogno di avere un'interfaccia utente o di reindirizzare un'uscita Ho bisogno di avviare un'app console e lasciare che faccia il lavoro.Non ho bisogno di alcun UI, quindi non è la via d'uscita –

0

Come ha detto pierre, non c'è modo di avere un'interfaccia utente per un servizio Windows (o nessun modo semplice). Quello che faccio in quel tipo di situazione è di avere un file di impostazioni che viene letto dal servizio su qualunque intervallo in cui il servizio funziona e dispone di un'applicazione autonoma che apporta modifiche al file delle impostazioni.

+0

Si prega di leggere i miei commenti ad altre risposte, non ho bisogno di un interfaccia utente per il servizio. –

0

L'app della console richiede l'interazione dell'utente? Se è così, è un no-no serio e dovresti riprogettare la tua domanda.Mentre ci sono alcuni hack per fare questo tipo di lavoro nelle vecchie versioni del sistema operativo, questo è garantito per rompere in futuro.

Se la tua app non richiede l'interazione dell'utente, allora forse il tuo problema è legato all'utente che il servizio è in esecuzione come. Prova ad assicurarti di essere eseguito come utente corretto o che l'utente e/o le risorse che stai utilizzando dispongano delle autorizzazioni appropriate.

Se è necessaria una sorta di interazione dell'utente, sarà necessario creare un'applicazione client e comunicare con il servizio e/o l'applicazione secondaria tramite rpc, socket o named pipe.

+0

Nessuna necessità di interazione ed. Ho provato l'account di sistema e il mio account amministratore. Penso che l'account amministratore debba essere di aiuto per avviare un'app console. –

0

I servizi sono necessari per connettersi al gestore di controllo servizi e fornire un feedback all'avvio (ad esempio, indicare SCM 'I'm alive!'). Ecco perché l'applicazione C# ha un modello di progetto diverso per i servizi. Avete due alternative:

  • Wrapp vostro exe su srvany.exe, come descritto in KB How To Create a User-Defined Service
  • avere il vostro C# app rilevare quando viene lanciato come un servizio e interruttore di comando per una (ad esempio riga di comando param.) classe che eredita da ServiceBase e implementa correttamente un servizio.
8

Ho fatto questo prima con successo - ho del codice a casa. Quando torno a casa stasera, aggiornerò questa risposta con il codice funzionante di un servizio che avvia un'applicazione per console.

Ho pensato di provare questo da zero. Ecco un codice che ho scritto che lancia un'applicazione per console. L'ho installato come servizio e l'ho eseguito e ha funzionato correttamente: si avvia cmd.exe (come si è visto in Task Manager) e vive per 10 secondi finché non invio il comando di uscita. Spero che questo aiuti la tua situazione in quanto funziona correttamente come previsto qui.

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

Sarebbe fantastico! Aspettativa davvero impaziente !!! :-) –

0

Ho un servizio di Windows, ed ho aggiunto la seguente linea al costruttore per il mio servizio:

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

Quando ho provato a eseguire questo, il Process.Start() è stata fatta chiamata, e non si è verificata alcuna eccezione. Tuttavia, l'applicazione calc.exe non è stata visualizzata. Per farlo funzionare, avevo modificato le proprietà per il mio servizio in Gestione controllo servizi per consentire l'interazione con il desktop. Dopo aver fatto ciò, Process.Start() ha aperto calc.exe come previsto.

Ma come altri hanno già detto, l'interazione con il desktop è disapprovata da Microsoft ed è stata essenzialmente disattivata in Vista. Quindi, anche se riesci a farlo funzionare in XP, non so se riuscirai a farlo funzionare in Vista.

-11

In esecuzione in Servizi Windows qualsiasi applicazione come ad esempio ".exe" è strana da fare perché l'algoritmo non è così efficace.

+1

Perché? Abbiamo applicazioni pubblicate sia come servizi di console che come servizi. Ad esempio, un'app per console è molto più facile da eseguire il debug. –

+0

La scrittura di istruzioni senza senso è ancora meno efficace – LastTribunal

+0

In che modo ciò influisce sull'efficacia dell'algoritmo? –

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

Prova ad aggiungere commenti utili con il tuo codice per descrivere cosa sta facendo e come risolve il problema piuttosto che pubblicare semplicemente il codice stesso. –

+1

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e/o su come questo codice risponde alla domanda migliora il suo valore a lungo termine. – JAL

Problemi correlati