Visual Studio kullanarak bir .net Windows Hizmeti için bir yükleyici oluşturma


Yanıtlar:


227

Hizmet projesinde aşağıdakileri yapın:

  1. Çözüm gezgininde hizmetler .cs dosyasına çift tıklayın. Tamamen gri bir ekran açmalı ve araç kutusundan bir şeyler sürüklemekten bahsediyor.
  2. Ardından gri alana sağ tıklayın ve yükleyici ekle'yi seçin. Bu, projenize bir yükleyici proje dosyası ekleyecektir.
  3. Sonra ProjectInstaller.cs (serviceProcessInstaller1 ve serviceInstaller1) tasarım görünümünde 2 bileşen olacaktır. Daha sonra, hizmet adı ve kullanıcı olarak çalışması gereken özellikleri gerektiği gibi ayarlamanız gerekir.

Şimdi bir kurulum projesi yapmanız gerekiyor. Yapılacak en iyi şey kurulum sihirbazını kullanmaktır.

  1. Çözümünüzü sağ tıklayın ve yeni bir proje ekleyin: Ekle> Yeni Proje> Kurulum ve Dağıtım Projeleri> Kurulum Sihirbazı

    a. Bu, Visual Studio'nun farklı sürümleri için biraz farklılık gösterebilir. b. Bulunduğu Visual Studio 2010: Şablonları Yükle> Diğer Proje Türleri> Kurulum ve Dağıtım> Visual Studio Yükleyici

  2. İkinci adımda "Windows Uygulaması için Kurulum Oluştur" u seçin.

  3. 3. adımda "Birincil çıktı ..." seçeneğini belirleyin.

  4. Bitirmek için tıklayın.

Ardından, doğru çıkışın eklendiğinden emin olmak için yükleyicinizi düzenleyin.

  1. Çözüm Gezgini'ndeki kurulum projesine sağ tıklayın.
  2. Görünüm> Özel İşlemler'i seçin. (VS2008'de Görünüm> Editör> Özel İşlemler olabilir)
  3. Özel Eylemler ağacında Yükle eylemine sağ tıklayın ve 'Özel Eylem Ekle ...' seçeneğini seçin.
  4. "Projede Öğe Seç" iletişim kutusunda Uygulama Klasörü'nü seçin ve Tamam'a tıklayın.
  5. "Birincil çıktı ..." seçeneğini belirlemek için Tamam'ı tıklatın. Yeni bir düğüm oluşturulmalıdır.
  6. Tamamlama, geri alma ve kaldırma işlemleri için 4 - 5. adımları tekrarlayın.

Çözümleyicinizin çıktı adını, çözümünüzdeki Installer projesine sağ tıklayıp Özellikler'i seçerek düzenleyebilirsiniz. 'Çıktı dosyası adı:' seçeneğini istediğiniz şekilde değiştirin. Hem yükleyici projesini seçerek ve özellikleri pencere bakarak, düzenleyebilir Product Name, Title, Manufacturer, vb ...

Sonra yükleyicinizi oluşturun ve bir MSI ve setup.exe üretecektir. Hizmetinizi dağıtmak için hangisini kullanmak istediğinizi seçin.


37
@El Ronnoco, cevaplamadan çok önce cevap aldım. Burada belgelemek istedim çünkü her 6-12 ayda bir aramak zorunda kalıyorum (ve bu kadar kolay olmamıştı) bu yüzden şimdi herkes için kolayca aranabilirim ve çabucak kendim bulabilirim :)
Kelsey

1
Ne yazık ki, bu da yanlış cevap. Evet, bunu kitaplarda ve MSDN'de bulacağınızı biliyorum, ancak Microsoft'ta bir grubun Microsoft'ta başka bir grupla konuşmadığı ve zaten çözülmüş bir soruna daha düşük bir çözüm bulduğu bir durum. Daha fazla bilgi için blog.iswix.com/2006/07/msi-vs-net.html adresine bakın .
Christopher Painter

9
@Christopher Painter MS yükleyicisini 2k5'ten beri kullanıyorum ve hiç problem yaşamadım. Buna katılıp katılmamanız ve bunu bir 'anti-desen' olarak kabul edip etmemeniz bu sorunun konusu değildir, b ile y'yi nasıl yapacağım değil, b ile nasıl yapacağım değil. Soruyu yayınladığımda dokümantasyon amaçlıydı.
Kelsey

3
O zaman 6 yıldır şanslısın, bilmiyorsun. Okumak isteyebilirsiniz: robmensching.com/blog/posts/2007/4/19/…
Christopher Painter

1
Service name contains invalid characters, is empty, or is too long (max length = 80)Yükleyiciyi eklerken bir hata alırsanız , gri alana tekrar sağ tıklayın, Özellikler'e gidin ve Hizmet Adı değerinin ayarlandığından emin olun.
wolfyuk

51

Kelsey'in kurulum sınıflarını servis projeme eklemek için ilk adımlarını takip ediyorum, ancak MSI veya setup.exe yükleyicisi oluşturmak yerine hizmeti kendiliğinden yükleme / kaldırma yapıyorum. İşte bir başlangıç ​​noktası olarak kullanabileceğiniz servislerimden bir örnek kod.

public static int Main(string[] args)
{
    if (System.Environment.UserInteractive)
    {
        // we only care about the first two characters
        string arg = args[0].ToLowerInvariant().Substring(0, 2);

        switch (arg)
        {
            case "/i":  // install
                return InstallService();

            case "/u":  // uninstall
                return UninstallService();

            default:  // unknown option
                Console.WriteLine("Argument not recognized: {0}", args[0]);
                Console.WriteLine(string.Empty);
                DisplayUsage();
                return 1;
        }
    }
    else
    {
        // run as a standard service as we weren't started by a user
        ServiceBase.Run(new CSMessageQueueService());
    }

    return 0;
}

private static int InstallService()
{
    var service = new MyService();

    try
    {
        // perform specific install steps for our queue service.
        service.InstallService();

        // install the service with the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException != null && ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service already installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

private static int UninstallService()
{
    var service = new MyQueueService();

    try
    {
        // perform specific uninstall steps for our queue service
        service.UninstallService();

        // uninstall the service from the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service not installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

1
Meraktan, kendi kendine kurulum / kurulum kaldırma hizmetine sahip olmanın faydası nedir? Hizmet kendini kurarsa, hizmeti ilk etapta kurmak için hizmeti ilk olarak nasıl başlatırsınız? Hizmeti yüklemeden başlatmak için bir mekanizma varsa, neden yüklemeyi hiç rahatsız etmiyorsunuz?
Kiley Naro

3
@Christopher - Yapmıyorum. Benim çözümüm, yazılım dağıtmak için kullanacağınız tam bir yükleyicinin yerini tutmaz. Katıştırılmış bilgisayarları katılımsız kiosklara yönlendiren yazılımlar yazdığım benimki gibi bazı durumlar için çalışan başka bir seçenek sunuyorum.

4
Bir üretim makinesine kurarken, yönetici olarak çalıştırmayı unutmayın. / İ parametresiyle EXE dosyasını çağıran bir BAT dosyası oluşturdum, ancak BAT dosyasını yönetici olarak yürütsem bile üretim ortamında çalışmadı. Yönetici olarak bir komut satırı istemi açmak ve açıkça (BAT dosyasını kullanmadan) / i EXE dosyasını çağırmak zorunda kaldı. En azından bu bana bir Windows Server 2012'de oldu.
Francisco Goldenstein

1
RE: Komut Satırında Çıkış Yok. VS 2017 Topluluğu kullanarak yeni hizmet projem varsayılan olarak Çıktı türü: Windows Applicationve Başlangıç ​​nesnesi: olarak ayarlandı (none). Çıktı türünü değiştirmek Console Applicationve başlangıç ​​nesnesimi ayarlamak zorunda kaldım myservice.Program. Farkında olmadığım sonuçlar varsa, lütfen tavsiye edin.
Jonathan

1
Örnek kodda yazım hataları var mı? Neden üç fark hizmeti var (CSMessageQueueService, MyService, MyQueueService)?
Nils Guillermin

27

Ne Kelsey, ne de Brendan çözümleri Visual Studio 2015 Topluluğu'nda benim için çalışmıyor.

Yükleyiciyle nasıl hizmet oluşturabileceğime ilişkin kısa adımlarım:

  1. Visual Studio'yu çalıştırın, File->New->Project
  2. 'Yüklü Şablonları Ara' alanına .NET Framework 4'ü seçin 'Hizmet'
  3. 'Windows Hizmeti'ni seçin. Ad ve Konum yazın. Düğmesine basın OK.
  4. Service1.cs dosyasına çift tıklayın, tasarımcıya sağ tıklayın ve 'Installer Ekle'yi seçin
  5. ProjectInstaller.cs dosyasına çift tıklayın. ServiceProcessInstaller1 için Özellikler sekmesini açın ve 'Hesap' özellik değerini 'LocalService' olarak değiştirin. ServiceInstaller1 için 'ServiceName' öğesini değiştirin ve 'StartType'ı' Otomatik 'olarak ayarlayın.
  6. ServiceInstaller1 öğesine çift tıklayın. Visual Studio serviceInstaller1_AfterInstallolay oluşturur . Kod yaz:

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
    
  7. Çözüm oluşturun. Projeye sağ tıklayın ve 'Klasörü Dosya Gezgini'nde Aç'ı seçin. Git bin \ Debug .

  8. Aşağıdaki komut dosyası ile install.bat oluşturun:

    :::::::::::::::::::::::::::::::::::::::::
    :: Automatically check & get admin rights
    :::::::::::::::::::::::::::::::::::::::::
    @echo off
    CLS 
    ECHO.
    ECHO =============================
    ECHO Running Admin shell
    ECHO =============================
    
    :checkPrivileges 
    NET FILE 1>NUL 2>NUL
    if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ) 
    
    :getPrivileges 
    if '%1'=='ELEV' (shift & goto gotPrivileges)  
    ECHO. 
    ECHO **************************************
    ECHO Invoking UAC for Privilege Escalation 
    ECHO **************************************
    
    setlocal DisableDelayedExpansion
    set "batchPath=%~0"
    setlocal EnableDelayedExpansion
    ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs" 
    ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs" 
    "%temp%\OEgetPrivileges.vbs" 
    exit /B 
    
    :gotPrivileges 
    ::::::::::::::::::::::::::::
    :START
    ::::::::::::::::::::::::::::
    setlocal & pushd .
    
    cd /d %~dp0
    %windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil /i "WindowsService1.exe"
    pause
    
  9. Dosyanın uninstall.bat oluşturun (kalem-ön muamele hattında değişiklik /iiçin /u)
  10. Hizmeti yüklemek ve başlatmak için install.bat komutunu çalıştırın, durdurmak ve kaldırmak için uninstall.bat komutunu çalıştırın.

14

VS2017 için "Microsoft Visual Studio 2017 Installer Projects" VS uzantısını eklemeniz gerekir. Bu size ek Visual Studio Installer proje şablonları verecektir. https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

Windows hizmetini yüklemek için yeni bir kurulum sihirbazı türü proje ekleyebilir ve Kelsey'in cevabındaki adımları takip edebilirsiniz https://stackoverflow.com/a/9021107/1040040


1

InstallUtil sınıfları (ServiceInstaller), Windows Installer topluluğu tarafından bir anti-desen olarak kabul edilir. Windows Installer'ın Hizmetler için yerleşik desteğe sahip olduğunu görmezden gelen, tekerleği yeniden işleyen kırılgan bir süreç.

Visual Studio dağıtım projelerinin (ayrıca Visual Studio'nun bir sonraki sürümünde dikkate alınmayan ve kullanımdan kaldırılmayan) hizmetler için yerel destek yoktur. Ancak birleştirme modüllerini tüketebilirler. Bu yüzden, hizmeti yükleyebilen ve daha sonra VDPROJ çözümünüzdeki birleştirme modülünü tüketen birleştirme modülü oluşturma işlemini anlamak için bu blog makalesine bir göz atacağım.

Windows Installer XML Kullanarak InstallShield'ı Artırmak - Windows Services

IsWiX Windows Servis Eğitimi

IsWiX Windows Hizmet Videosu


1
Eski Visual Studio'da, kolay oluşturma yükleyicisine sahip bir dağıtım projesi vardı. Şimdi üçüncü taraf yazılım bileşenini satın almak zorunda mıyım?
Alexey Obukhov

@AlexeyObukhov Wix'i ücretsiz olarak kullanabilirsiniz, VS'nin kendisi bunu kullanır, ancak Wix'le ilgili sorun Git'e yakın problem - aynı dikey öğrenme eğrisi ile aynıdır.
Alan B
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.