Oprócz service.StartType = ServiceStartMode.Automatic moja usługa nie uruchamia się po instalacji
Rozwiązanie
Wstawiłem ten kod do mojego ProjectInstaller
protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
base.OnAfterInstall(savedState);
using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName))
serviceController.Start();
}
Dzięki ScottTx i Francis B.
.net
windows-services
installer
Jader Dias
źródło
źródło
Odpowiedzi:
Możesz to wszystko zrobić z poziomu pliku wykonywalnego usługi w odpowiedzi na zdarzenia wywołane z procesu InstallUtil. Zastąp zdarzenie OnAfterInstall, aby użyć klasy ServiceController do uruchomienia usługi.
http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx
źródło
Mam napisali procedurę krok po kroku do tworzenia usługi Windows w C # tutaj . Wygląda na to, że jesteś przynajmniej do tego momentu, a teraz zastanawiasz się, jak uruchomić usługę po jej zainstalowaniu. Ustawienie właściwości StartType na Automatic spowoduje automatyczne uruchomienie usługi po ponownym uruchomieniu systemu, ale nie (jak odkryłeś) automatycznie uruchomi usługę po instalacji.
Nie pamiętam, gdzie go pierwotnie znalazłem (być może Marc Gravell?), Ale znalazłem w Internecie rozwiązanie, które umożliwia zainstalowanie i uruchomienie usługi poprzez faktyczne jej uruchomienie. Oto krok po kroku:
Zorganizuj
Main()
funkcję swojej usługi w następujący sposób:static void Main(string[] args) { if (args.Length == 0) { // Run your service normally. ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()}; ServiceBase.Run(ServicesToRun); } else if (args.Length == 1) { switch (args[0]) { case "-install": InstallService(); StartService(); break; case "-uninstall": StopService(); UninstallService(); break; default: throw new NotImplementedException(); } } }
Oto kod pomocniczy:
using System.Collections; using System.Configuration.Install; using System.ServiceProcess; private static bool IsInstalled() { using (ServiceController controller = new ServiceController("YourServiceName")) { try { ServiceControllerStatus status = controller.Status; } catch { return false; } return true; } } private static bool IsRunning() { using (ServiceController controller = new ServiceController("YourServiceName")) { if (!IsInstalled()) return false; return (controller.Status == ServiceControllerStatus.Running); } } private static AssemblyInstaller GetInstaller() { AssemblyInstaller installer = new AssemblyInstaller( typeof(YourServiceType).Assembly, null); installer.UseNewContext = true; return installer; }
Kontynuując kod pomocniczy ...
private static void InstallService() { if (IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Install(state); installer.Commit(state); } catch { try { installer.Rollback(state); } catch { } throw; } } } catch { throw; } } private static void UninstallService() { if ( !IsInstalled() ) return; try { using ( AssemblyInstaller installer = GetInstaller() ) { IDictionary state = new Hashtable(); try { installer.Uninstall( state ); } catch { throw; } } } catch { throw; } } private static void StartService() { if ( !IsInstalled() ) return; using (ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Running ) { controller.Start(); controller.WaitForStatus( ServiceControllerStatus.Running, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } private static void StopService() { if ( !IsInstalled() ) return; using ( ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Stopped ) { controller.Stop(); controller.WaitForStatus( ServiceControllerStatus.Stopped, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } }
W tym momencie, po zainstalowaniu usługi na maszynie docelowej, po prostu uruchom ją z wiersza poleceń (jak każda zwykła aplikacja) z
-install
argumentem wiersza poleceń, aby zainstalować i uruchomić usługę.Myślę, że omówiłem wszystko, ale jeśli okaże się, że to nie działa, daj mi znać, abym mógł zaktualizować odpowiedź.
źródło
YourServiceType
jest tym,ProjectInstaller
który dodałeś do usługi, która zawieraServiceInstaller
iServiceProcessInstaller
Visual Studio
Jeśli tworzysz projekt instalacyjny za pomocą VS, możesz utworzyć akcję niestandardową, która wywołała metodę .NET w celu uruchomienia usługi. Ale tak naprawdę nie jest zalecane używanie zarządzanej akcji niestandardowej w MSI. Zobacz tę stronę .
ServiceController controller = new ServiceController(); controller.MachineName = "";//The machine where the service is installed; controller.ServiceName = "";//The name of your service installed in Windows Services; controller.Start();
InstallShield lub Wise
Jeśli używasz InstallShield lub Wise, te aplikacje zapewniają opcję uruchomienia usługi. Na przykład w przypadku Wise musisz dodać akcję kontroli usługi. W tej akcji określasz, czy chcesz uruchomić, czy zatrzymać usługę.
Wix
Korzystając z Wix, musisz dodać następujący kod xml pod komponentem swojej usługi. Więcej informacji na ten temat można znaleźć na tej stronie .
<ServiceInstall Id="ServiceInstaller" Type="ownProcess" Vital="yes" Name="" DisplayName="" Description="" Start="auto" Account="LocalSystem" ErrorControl="ignore" Interactive="no"> <ServiceDependency Id="????"/> ///Add any dependancy to your service </ServiceInstall>
źródło
Musisz dodać akcję niestandardową na końcu sekwencji „ExecuteImmediate” w pliku MSI, używając nazwy komponentu EXE lub partii (start sc) jako źródła. Nie sądzę, aby można to zrobić w programie Visual Studio, być może będziesz musiał użyć do tego prawdziwego narzędzia autorskiego MSI.
źródło
Aby uruchomić go zaraz po instalacji, generuję plik wsadowy z installutil, a następnie sc start
Nie jest idealny, ale działa ....
źródło
Użyj klasy .NET ServiceController, aby ją uruchomić, lub wydaj polecenie wiersza polecenia, aby ją uruchomić - „net start nazwa usługi”. Tak czy inaczej działa.
źródło
Aby dodać do odpowiedzi ScottTx, oto rzeczywisty kod uruchamiający usługę, jeśli robisz to w sposób Microsoft (tj. Używając projektu instalacyjnego itp.)
(przepraszam za kod VB.net, ale na tym utknąłem)
Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall Dim sc As New ServiceController() sc.ServiceName = ServiceInstaller1.ServiceName If sc.Status = ServiceControllerStatus.Stopped Then Try ' Start the service, and wait until its status is "Running". sc.Start() sc.WaitForStatus(ServiceControllerStatus.Running) ' TODO: log status of service here: sc.Status Catch ex As Exception ' TODO: log an error here: "Could not start service: ex.Message" Throw End Try End If End Sub
Aby utworzyć powyższą procedurę obsługi zdarzeń, przejdź do projektanta ProjectInstaller, w którym znajdują się 2 kontrolery. Kliknij formant ServiceInstaller1. Przejdź do okna właściwości pod zdarzeniami, a tam znajdziesz zdarzenie AfterInstall.
Uwaga: nie umieszczaj powyższego kodu w zdarzeniu AfterInstall dla ServiceProcessInstaller1. To nie zadziała, biorąc pod uwagę doświadczenie. :)
źródło
Najłatwiejsze rozwiązanie można znaleźć tutaj install-windows-service-without-installutil-exe autorstwa @ Hoàng Long
@echo OFF echo Stopping old service version... net stop "[YOUR SERVICE NAME]" echo Uninstalling old service version... sc delete "[YOUR SERVICE NAME]" echo Installing service... rem DO NOT remove the space after "binpath="! sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto echo Starting server complete pause
źródło