Kurulumdan hemen sonra bir .NET Windows Hizmeti nasıl başlatılır?


88

Service.StartType = ServiceStartMode.Automatic yanında, kurulumdan sonra hizmetim başlamıyor

Çözüm

Bu kodu ProjectInstaller'ıma ekledim

protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
    base.OnAfterInstall(savedState);
    using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName))
        serviceController.Start();
}

ScottTx ve Francis B.'ye teşekkürler.


Kurulumdan hemen sonra başlamıyor veya yeniden başlattığınızda başlamıyor mu?
Chris Van Opstal

Yanıtlar:


21

Bunu, InstallUtil işleminden tetiklenen olaylara yanıt olarak yürütülebilir hizmetinizin içinden yapabilirsiniz. Hizmeti başlatmak için ServiceController sınıfını kullanmak için OnAfterInstall olayını geçersiz kılın.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx


3
Bu güzel bir çözüm, ancak yine de InstallUtil yardımcı programının kullanılmasını gerektiriyor. InstallUtil'i zaten kurulumunuzun bir parçası olarak teslim ediyorsanız, bu en mantıklıdır. Ancak, InstallUtil'i paketlemekten vazgeçmek istiyorsanız, komut satırı çözümünü kullanın.
Matt Davis

182

Burada C #'da bir Windows hizmeti oluşturmak için adım adım bir prosedür yayınladım . Görünüşe göre en azından bu noktaya gelmişsiniz ve şimdi hizmet yüklendikten sonra nasıl başlatılacağını merak ediyorsunuz. StartType özelliğinin Otomatik olarak ayarlanması, sisteminizi yeniden başlattıktan sonra hizmetin otomatik olarak başlamasına neden olur, ancak kurulumdan sonra (keşfettiğiniz gibi) hizmetinizi otomatik olarak başlatmaz.

Başlangıçta nerede bulduğumu hatırlamıyorum (belki Marc Gravell?), Ancak hizmetinizi gerçekten kendi başına çalıştırarak kurmanıza ve başlatmanıza izin veren çevrimiçi bir çözüm buldum. İşte adım adım:

  1. Main()Hizmetinizin işlevini şu şekilde yapılandırın :

    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();
            }
        }
    }
    
  2. Destekleyici kod şu şekildedir:

    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;
    }
    
  3. Destekleyici kod ile devam ediyoruz ...

    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;
            }
        }
    }
    
  4. Bu noktada, hizmetinizi hedef makineye yükledikten sonra, hizmetinizi -installkurmak ve başlatmak için hizmetinizi komut satırından (herhangi bir sıradan uygulama gibi) komut satırı argümanıyla çalıştırın.

Sanırım her şeyi ele aldım, ancak bunun işe yaramadığını fark ederseniz, lütfen cevabı güncelleyebilmem için bana bildirin.


13
Bu çözümün InstallUtil.exe kullanılmasını gerektirmediğini, bu nedenle onu yükleme programınızın bir parçası olarak teslim etmeniz gerekmediğini unutmayın.
Matt Davis

3
Boş "catch {throw;}" cümlelerinin anlamı nedir? Ayrıca, hataları "Rollback ()" ile gizlemek muhtemelen iyi bir fikir değildir çünkü bu durum sistemi temelde tanımsız bir durumda bırakır, sanırım (bir hizmeti kurmaya çalıştınız, ortada bir yerde başarısız oldunuz ve geri alamadınız ). Kullanıcıya en azından balıklı bir şey olduğunu "göstermelisiniz" - yoksa Rollback () işlevi konsola bazı mesajlar mı yazıyor?
Christian.K

5
Geri alma, konsola veri yazar. Boş yakalama bloklarına gelince, bu bir hata ayıklama işi. Oluşabilecek istisnaları incelemek için throw ifadesine bir kesme noktası koyabilirim.
Matt Davis

4
Hata alıyorum Hata: 'YourServiceType' türü veya ad alanı adı bulunamadı (kullanma yönergesi veya bir derleme başvurusu eksik mi?
Yogesh

5
YourServiceTypeolduğunu ProjectInstallersen içeren hizmete eklenen ServiceInstallerveServiceProcessInstaller
Bansi

6

Görsel stüdyo

VS ile bir kurulum projesi oluşturuyorsanız, hizmeti başlatmak için .NET yöntemini çağıran özel bir eylem oluşturabilirsiniz. Ancak, bir MSI'da yönetilen özel eylem kullanılması gerçekten önerilmez. Bu sayfaya bakın .

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 veya Wise

InstallShield veya Wise kullanıyorsanız, bu uygulamalar hizmeti başlatma seçeneği sunar. Wise ile örnek olarak, bir servis kontrol eylemi eklemeniz gerekir. Bu eylemde, hizmeti başlatmak mı yoksa durdurmak mı istediğinizi belirtirsiniz.

Wix

Wix'i kullanarak hizmetinizin bileşeninin altına aşağıdaki xml kodunu eklemeniz gerekir. Bununla ilgili daha fazla bilgi için bu sayfayı kontrol edebilirsiniz .

<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>

5

MSI'daki 'ExecuteImmediate' dizisinin sonuna, kaynak olarak EXE bileşen adını veya toplu işi (sc start) kullanarak bir Özel Eylem eklemeniz gerekir. Bunun Visual Studio ile yapılabileceğini sanmıyorum, bunun için gerçek bir MSI yazma aracı kullanmanız gerekebilir.


4

Kurulumdan hemen sonra başlatmak için, installutil ve ardından sc start ile bir toplu iş dosyası oluşturuyorum

İdeal değil ama işe yarıyor ....


4

Başlatmak için .NET ServiceController sınıfını kullanın veya başlatmak için komut satırı komutunu verin --- "net start servicename". Her iki şekilde de çalışır.


4

ScottTx'in cevabına eklemek için, işte Microsoft yöntemiyle yapıyorsanız hizmeti başlatmak için gerçek kod. (yani bir Kurulum projesi vb. Kullanarak) .

(VB.net kodunu özür dilerim, ama benim takıldığım şey bu)

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

Yukarıdaki olay işleyicisini oluşturmak için, 2 denetimin bulunduğu ProjectInstaller tasarımcısına gidin. ServiceInstaller1 kontrolüne tıklayın. Olaylar altındaki özellikler penceresine gidin ve orada AfterInstall olayını bulacaksınız.

Not: Yukarıdaki kodu ServiceProcessInstaller1 için AfterInstall olayının altına koymayın. Deneyimle işe yaramayacak. :)


VB.net kodu fena değil! Birden çok dilde çalışanlarımız için, kodu C'den dönüştürmek zorunda kalmamak güzel!
Steve Reed Sr

Teşekkürler, bu bir hizmeti otomatik olarak nasıl başlatacağımı anlamama yardımcı oldu.
Charles Owen

0

En kolay çözüm burada, install-windows-service-without-installutil-exe tarafından @ Hoàng Long tarafından bulunur.

@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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.