171 votes

Comment créer un programme d'installation pour un service Windows .net à l'aide de Visual Studio ?

Comment créer un programme d'installation pour un service Windows que j'ai créé à l'aide de Visual Studio ?

0 votes

Ceci est déjà documenté dans l'article suivant de Microsoft KB : support.microsoft.com/fr/us/kb/816169

2 votes

@slayernoah le lien semble être cassé. Avez-vous d'autres références ?

267voto

Kelsey Points 26456

Dans le cadre du projet de service, faites ce qui suit :

  1. Dans l'explorateur de solutions, double-cliquez sur le fichier .cs de vos services. Cela devrait faire apparaître un écran tout gris où il est question de faire glisser des éléments de la boîte à outils.
  2. Ensuite, faites un clic droit sur la zone grise et sélectionnez ajouter un installateur. Cela ajoutera un fichier de projet d'installation à votre projet.
  3. Vous aurez alors 2 composants sur la vue de conception du ProjectInstaller.cs (serviceProcessInstaller1 et serviceInstaller1). Vous devez ensuite configurer les propriétés selon vos besoins, comme le nom du service et l'utilisateur sous lequel il doit fonctionner.

Vous devez maintenant créer un projet d'installation. La meilleure chose à faire est d'utiliser l'assistant d'installation.

  1. Faites un clic droit sur votre solution et ajoutez un nouveau projet : Ajouter > Nouveau projet > Projets d'installation et de déploiement > Assistant d'installation

    a. Cela peut varier légèrement pour les différentes versions de Visual Studio. b. Visual Studio 2010, il se trouve dans : Modèles d'installation > Autres types de projets > Configuration et déploiement > Visual Studio Installer

  2. À la deuxième étape, sélectionnez "Créer une configuration pour une application Windows".

  3. À la troisième étape, sélectionnez "Sortie primaire de...".

  4. Cliquez jusqu'à la fin.

Ensuite, modifiez votre installateur pour vous assurer que la sortie correcte est incluse.

  1. Cliquez avec le bouton droit de la souris sur le projet d'installation dans l'explorateur de solutions.
  2. Sélectionnez View > Custom Actions. (Dans VS2008, il peut s'agir de Affichage > Éditeur > Actions personnalisées).
  3. Cliquez avec le bouton droit de la souris sur l'action Installer dans l'arbre des actions personnalisées et sélectionnez "Ajouter une action personnalisée...".
  4. Dans la boîte de dialogue "Select Item in Project", sélectionnez Application Folder et cliquez sur OK.
  5. Cliquez sur OK pour sélectionner l'option "Primary output from...". Un nouveau nœud devrait être créé.
  6. Répétez les étapes 4 et 5 pour les actions de validation, d'annulation et de désinstallation.

Vous pouvez modifier le nom de la sortie du programme d'installation en cliquant avec le bouton droit de la souris sur le projet d'installation dans votre solution et en sélectionnant Propriétés. Changez le "Nom du fichier de sortie :" en ce que vous voulez. En sélectionnant également le projet d'installation et en consultant la fenêtre des propriétés, vous pouvez modifier le nom du fichier de sortie de l'installateur. Product Name , Title , Manufacturer etc...

Ensuite, construisez votre installateur et il produira un MSI et un setup.exe. Choisissez celui que vous voulez utiliser pour déployer votre service.

40 votes

@El Ronnoco, j'avais la réponse bien avant de poster. Je voulais la documenter ici parce que je dois toujours la chercher tous les 6 à 12 mois (et elle n'a pas été si facile à trouver), donc maintenant elle est facilement consultable pour tout le monde et je peux la trouver moi-même rapidement :)

1 votes

Malheureusement, c'est aussi la mauvaise réponse. Oui, je sais que vous trouverez cela dans les livres et sur MSDN, mais c'est un cas où un groupe de Microsoft n'a pas parlé à un autre groupe de Microsoft et a proposé une solution inférieure à un problème qui avait déjà été résolu. Voir blog.iswix.com/2006/07/msi-vs-net.html pour plus d'informations.

11 votes

@Christopher Painter J'utilise le programme d'installation de MS depuis 2k5 et il n'a jamais eu de problème. Que vous soyez d'accord ou non avec cette méthode et que vous la considériez comme un "anti-modèle" n'est pas le sujet de cette question, il s'agit de savoir comment faire x avec y, et non comment faire a avec b. Lorsque j'ai posté la question, c'était à des fins de documentation.

55voto

Brendan Leber Points 361

Je suis la première série d'étapes de Kelsey pour ajouter les classes d'installation à mon projet de service, mais au lieu de créer un installateur MSI ou setup.exe, je fais en sorte que le service s'installe/désinstalle automatiquement. Voici un exemple de code d'un de mes services que vous pouvez utiliser comme point de départ.

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 votes

Par curiosité, quel est l'avantage d'avoir un service qui s'installe et se désinstalle tout seul ? Si le service s'installe de lui-même, comment démarrer le service pour qu'il puisse être installé en premier lieu ? S'il existe un mécanisme permettant de démarrer le service sans l'installer, pourquoi prendre la peine de l'installer ?

0 votes

Le service n'est pas en marche quand il s'installe. System.Environment.UserInteractive est vrai lorsque l'exécutable est lancé depuis une console interactive par un utilisateur. Le code vérifie alors la ligne de commande pour savoir s'il doit s'installer ou se désinstaller. Une fois que le service s'est installé, vous devez le démarrer via le panneau de configuration des services ou en utilisant quelque chose comme "net start MyService".

0 votes

@BrendanLeber Je ne pense pas que vous ayez besoin de faire tout cela. Sélectionnez simplement ServiceInstaller1 sur le ProjectInstaller.cs dans votre projet de service et regardez ensuite la fenêtre des propriétés. Définissez le StartType à la propriété Automatic et il démarrera dès qu'il sera installé... Je ne pense pas que vous ayez besoin de tout ce code ou de cette complexité.

30voto

Alexey Obukhov Points 521

Ni Kelsey, ni les solutions de Brendan ne fonctionnent pour moi dans Visual Studio 2015 Community.

Voici mes brèves étapes pour créer un service avec l'installateur :

  1. Lancez Visual Studio, allez dans File->New->Project

  2. Sélectionnez .NET Framework 4, dans 'Search Installed Templates' tapez Service

  3. Sélectionnez "Service Windows". Saisissez le nom et l'emplacement. Appuyez sur OK .

  4. Double-cliquez sur Service1.cs, cliquez à droite dans le concepteur et sélectionnez "Ajouter un installateur".

  5. Double cliquez sur ProjectInstaller.cs. Pour serviceProcessInstaller1, ouvrez l'onglet Propriétés et changez la valeur de la propriété 'Account' en 'LocalService'. Pour serviceInstaller1, modifiez 'ServiceName' et définissez 'StartType' sur 'Automatic'.

  6. Double-cliquez sur serviceInstaller1. Visual Studio crée serviceInstaller1_AfterInstall événement. Écrire le code :

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
  7. Solution de construction. Faites un clic droit sur le projet et sélectionnez "Ouvrir le dossier dans l'explorateur de fichiers". Allez à bin \Debug .

  8. Créez install.bat avec le script ci-dessous :

    :::::::::::::::::::::::::::::::::::::::::
    :: 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. Créer le fichier uninstall.bat (changement dans la ligne pen-ult /i a /u )

  10. Pour installer et démarrer le service, exécutez install.bat, pour l'arrêter et le désinstaller, exécutez uninstall.bat.

16voto

ljsg Points 74

Pour VS2017, vous devrez ajouter l'extension VS "Microsoft Visual Studio 2017 Installer Projects". Cela vous donnera des modèles supplémentaires de projets Visual Studio Installer. https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

Pour installer le service Windows, vous pouvez ajouter un nouveau projet de type assistant d'installation et suivre les étapes de la réponse de Kelsey. https://stackoverflow.com/a/9021107/1040040

1voto

Christopher Painter Points 32519

Les classes InstallUtil (ServiceInstaller) sont considérées comme un anti-modèle par la communauté Windows Installer. Il s'agit d'une réinvention de la roue, fragile et hors processus, qui ignore le fait que Windows Installer dispose d'une prise en charge intégrée des services.

Les projets de déploiement Visual Studio (également peu appréciés et dépréciés dans la prochaine version de Visual Studio) n'ont pas de support natif pour les services. Mais ils peuvent consommer des modules de fusion. Je vous invite donc à consulter cet article de blog pour comprendre comment créer un module de fusion en utilisant Windows Installer XML qui peut exprimer le service et ensuite consommer ce module de fusion dans votre solution VDPROJ.

Compléter InstallShield en utilisant Windows Installer XML - Services Windows

Tutoriel sur le service Windows IsWiX

Vidéo du service Windows IsWiX

1 votes

Dans l'ancien Visual Studio, il y avait un projet de déploiement, avec un installateur facile à créer. Maintenant, je dois acheter un composant logiciel tiers ?

0 votes

@AlexeyObukhov Vous pouvez utiliser Wix gratuitement, c'est ce que VS lui-même utilise, mais le problème avec Wix est le même que celui avec Git - la courbe d'apprentissage quasi verticale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X