Come creare un programma di installazione per un servizio Windows .net utilizzando Visual Studio


Risposte:


227

Nel progetto di servizio procedi come segue:

  1. In Esplora soluzioni fare doppio clic sul file .cs dei servizi. Dovrebbe far apparire uno schermo tutto grigio e parla del trascinamento di oggetti dalla casella degli strumenti.
  2. Quindi fare clic con il pulsante destro del mouse sull'area grigia e selezionare Aggiungi programma di installazione. Ciò aggiungerà un file di progetto del programma di installazione al progetto.
  3. Quindi avrai 2 componenti nella vista di progettazione di ProjectInstaller.cs (serviceProcessInstaller1 e serviceInstaller1). Dovresti quindi impostare le proprietà di cui hai bisogno, come il nome del servizio e l'utente che dovrebbe essere eseguito come.

Ora devi creare un progetto di installazione. La cosa migliore da fare è utilizzare la procedura guidata di configurazione.

  1. Fare clic con il tasto destro del mouse sulla soluzione e aggiungere un nuovo progetto: Aggiungi> Nuovo progetto> Progetti di installazione e distribuzione> Installazione guidata

    un. Ciò potrebbe variare leggermente per le diverse versioni di Visual Studio. b. Visual Studio 2010 si trova in: Modelli di installazione> Altri tipi di progetto> Installazione e distribuzione> Programma di installazione di Visual Studio

  2. Nel secondo passaggio selezionare "Crea un'installazione per un'applicazione Windows".

  3. Al 3 ° passaggio, selezionare "Output primario da ..."

  4. Fai clic per finire.

Quindi modifica il tuo programma di installazione per assicurarti che sia incluso l'output corretto.

  1. Fare clic con il tasto destro sul progetto di installazione in Esplora soluzioni.
  2. Seleziona Visualizza> Azioni personalizzate. (In VS2008 potrebbe essere Visualizza> Editor> Azioni personalizzate)
  3. Fai clic con il pulsante destro del mouse sull'azione Installa nella struttura Azioni personalizzate e seleziona "Aggiungi azione personalizzata ..."
  4. Nella finestra di dialogo "Seleziona elemento nel progetto", selezionare Cartella applicazione e fare clic su OK.
  5. Fare clic su OK per selezionare l'opzione "Output primario da ...". È necessario creare un nuovo nodo.
  6. Ripetere i passaggi da 4 a 5 per le azioni di commit, rollback e disinstallazione.

È possibile modificare il nome dell'output del programma di installazione facendo clic con il pulsante destro del mouse sul progetto Installer nella soluzione e selezionare Proprietà. Cambia il 'Nome del file di output:' come preferisci. Selezionando il progetto di installazione come bene e guardando le proprietà di Windows, è possibile modificare il Product Name, Title, Manufacturer, ecc ...

Successivamente costruisci il tuo programma di installazione e produrrà un MSI e un setup.exe. Scegli quello che vuoi usare per distribuire il tuo servizio.


37
@El Ronnoco, ho avuto la risposta molto prima di pubblicare. Ho voluto documentarlo qui perché devo sempre cercarlo ogni 6 - 12 mesi (e non è stato così facile da trovare), quindi ora lo trovo facilmente ricercabile per tutti e posso trovarlo da solo :)
Kelsey,

1
Sfortunatamente, è anche la risposta sbagliata. Sì, lo so che lo troverai nei libri e in MSDN, ma è un caso in cui un gruppo in Microsoft non ha parlato con un altro gruppo in Microsoft e ha trovato una soluzione inferiore a un problema che era già stato risolto. Vedi blog.iswix.com/2006/07/msi-vs-net.html per ulteriori informazioni.
Christopher Painter,

9
@Christopher Painter Uso il programma di installazione MS dal2k5 e non ha mai avuto problemi. Indipendentemente dal fatto che tu sia d'accordo e lo consideri un "anti-pattern" non è il punto di questa domanda, è come faccio x con y, non come faccio a con b. Quando ho pubblicato la domanda era a scopo di documentazione.
Kelsey,

3
Quindi sei stato fortunato per 6 anni che non lo conosci. Potresti voler leggere: robmensching.com/blog/posts/2007/4/19/…
Christopher Painter,

1
Se si verifica un Service name contains invalid characters, is empty, or is too long (max length = 80)errore durante l'aggiunta del programma di installazione, fare nuovamente clic con il pulsante destro del mouse nell'area grigia, andare su Proprietà e assicurarsi che il valore del nome del servizio sia impostato.
Wolfyuk,

51

Seguo la prima serie di passaggi di Kelsey per aggiungere le classi del programma di installazione al mio progetto di servizio, ma invece di creare un programma di installazione MSI o setup.exe, il servizio viene autoinstallato / disinstallato. Ecco un po 'di codice di esempio da uno dei miei servizi che puoi usare come punto di partenza.

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
Per curiosità, qual è il vantaggio di avere un servizio di autoinstallazione / disinstallazione? Se il servizio si installa da solo, come si avvia il servizio per primo in modo che possa essere installato in primo luogo? Se esiste un meccanismo per avviare il servizio senza installarlo, perché preoccuparsi di installarlo?
Kiley Naro,

3
@Christopher - Io no. La mia soluzione non sostituisce un programma di installazione completo che utilizzeresti per distribuire il software. Sto presentando un'altra opzione che funziona per alcune situazioni, come la mia in cui scrivo software che guida PC incorporati in chioschi non presidiati.

4
Quando lo installi su una macchina di produzione, ricordati di eseguirlo come amministratore. Ho creato un file BAT che chiama il file EXE con il parametro / i ma non ha funzionato nell'ambiente di produzione, anche se ho eseguito il file BAT come amministratore. Ho dovuto aprire un prompt della riga di comando come amministratore e richiamare esplicitamente il file EXE / i (senza utilizzare il file BAT). Almeno mi è successo su un Windows Server 2012.
Francisco Goldenstein,

1
RE: Nessun output sulla riga di comando. Utilizzando VS 2017 Community mio nuovo progetto di servizio impostazione predefinita: Tipo di uscita: Windows Applicatione oggetto di avvio: (none). Ho dovuto cambiare il tipo di output Console Applicatione impostare il mio oggetto di avvio, ad es myservice.Program. Se potrebbero esserci delle ramificazioni di cui non sono a conoscenza, si prega di avvisare.
Jonathan,

1
Il codice di esempio ha errori di battitura? Perché ci sono tre differenze di servizi (CSMessageQueueService, MyService, MyQueueService)?
Nils Guillermin,

27

Né Kelsey, né le soluzioni Brendan non funzionano per me nella community di Visual Studio 2015.

Ecco i miei brevi passaggi su come creare un servizio con l'installer:

  1. Esegui Visual Studio, vai a File->New->Project
  2. Selezionare .NET Framework 4, in "Cerca modelli installati" digitare "Servizio"
  3. Seleziona "Servizio Windows". Digitare nome e posizione. Press OK.
  4. Fare doppio clic su Service1.cs, fare clic con il tasto destro in designer e selezionare 'Aggiungi programma di installazione'
  5. Fare doppio clic su ProjectInstaller.cs. Per serviceProcessInstaller1 aprire la scheda Proprietà e modificare il valore della proprietà "Account" in "LocalService". Per serviceInstaller1 cambiare 'ServiceName' e impostare 'StartType' su 'Automatic'.
  6. Fare doppio clic su serviceInstaller1. Visual Studio crea un serviceInstaller1_AfterInstallevento. Scrivi il codice:

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
    
  7. Crea soluzione. Fare clic con il tasto destro del mouse sul progetto e selezionare "Apri cartella in Esplora file". Vai a bin \ Debug .

  8. Crea install.bat con lo script seguente:

    :::::::::::::::::::::::::::::::::::::::::
    :: 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. Crea il file uninstall.bat (modifica nella riga pen-ult /iin /u)
  10. Per installare e avviare il servizio, eseguire install.bat, per arrestare e disinstallare eseguire uninstall.bat

14

Per VS2017 dovrai aggiungere l'estensione VS "Progetti di installazione di Microsoft Visual Studio 2017". Ciò fornirà ulteriori modelli di progetto del programma di installazione di Visual Studio. https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

Per installare il servizio Windows è possibile aggiungere un nuovo progetto di tipo procedura guidata e seguire i passaggi dalla risposta di Kelsey https://stackoverflow.com/a/9021107/1040040


1

Le classi InstallUtil (ServiceInstaller) sono considerate anti-pattern dalla community di Windows Installer. È un reinventamento fragile, fuori processo, che ignora il fatto che Windows Installer ha un supporto integrato per i servizi.

I progetti di distribuzione di Visual Studio (anche non molto apprezzati e deprecati nella prossima versione di Visual Studio) non dispongono di supporto nativo per i servizi. Ma possono consumare moduli di unione. Quindi darei un'occhiata a questo articolo del blog per capire come creare un modulo di unione utilizzando XML di Windows Installer in grado di esprimere il servizio e quindi utilizzare quel modulo di unione nella soluzione VDPROJ.

Aumentare InstallShield utilizzando XML di Windows Installer - Servizi di Windows

Tutorial del servizio Windows IsWiX

Video del servizio Windows IsWiX


1
Nel vecchio Visual Studio esisteva un progetto di distribuzione, con un semplice programma di installazione per la creazione. Ora devo acquistare un componente software di terze parti?
Alexey Obukhov,

@AlexeyObukhov Puoi usare Wix gratuitamente, questo è ciò che VS stesso usa, ma il problema con Wix è lo stesso del problema con Git: la curva di apprendimento quasi verticale.
Alan B,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.