Visual Studioを使用して.net Windowsサービスのインストーラーを作成する方法


回答:


227

サービスプロジェクトで、次の操作を行います。

  1. ソリューションエクスプローラーで、サービスの.csファイルをダブルクリックします。すべて灰色の画面が表示され、ツールボックスからのドラッグに関する説明が表示されます。
  2. 次に、灰色の領域を右クリックして、インストーラーの追加を選択します。これにより、インストーラープロジェクトファイルがプロジェクトに追加されます。
  3. 次に、ProjectInstaller.csのデザインビューに2つのコンポーネント(serviceProcessInstaller1とserviceInstaller1)があります。次に、サービス名や実行するユーザーなど、必要に応じてプロパティを設定する必要があります。

次に、セットアッププロジェクトを作成する必要があります。最善の方法は、セットアップウィザードを使用することです。

  1. ソリューションを右クリックして、新しいプロジェクトを追加します。追加>新規プロジェクト>セットアップおよびデプロイメントプロジェクト>セットアップウィザード

    a。これは、Visual Studioのバージョンによって若干異なる場合があります。b。Visual Studio 2010は次の場所にあります:テンプレートのインストール>その他のプロジェクトタイプ>セットアップと展開> Visual Studioインストーラ

  2. 2番目のステップで、「Windowsアプリケーションのセットアップを作成する」を選択します。

  3. 3番目のステップで、[プライマリ出力...]を選択します。

  4. クリックして終了します。

次に、インストーラーを編集して、正しい出力が含まれていることを確認します。

  1. ソリューションエクスプローラーでセットアッププロジェクトを右クリックします。
  2. [表示]> [カスタムアクション]を選択します。(VS2008では、表示>エディター>カスタムアクションの場合があります)
  3. カスタムアクションツリーで[インストール]アクションを右クリックし、[カスタムアクションの追加...]を選択します。
  4. [プロジェクト内のアイテムの選択]ダイアログで、[アプリケーションフォルダー]を選択し、[OK]をクリックします。
  5. [OK]をクリックして、[プライマリ出力...]オプションを選択します。新しいノードを作成する必要があります。
  6. コミット、ロールバック、およびアンインストールのアクションについて、手順4〜5を繰り返します。

ソリューションのインストーラープロジェクトを右クリックして[プロパティ]を選択すると、インストーラーの出力名を編集できます。「出力ファイル名:」を任意の名前に変更します。同様インストーラプロジェクトを選択し、プロパティ・ウィンドウで見ることによって、あなたが編集することができProduct NameTitleManufacturer、等...

次にインストーラーをビルドすると、MSIとsetup.exeが生成されます。サービスのデプロイに使用するものを選択します。


37
@El Ronnoco、投稿するずっと前から答えがあった。6か月から12か月ごとに検索する必要があるため(そして簡単に見つけることができなかったため)、ここで文書化したかったので、誰でも簡単に検索でき、自分ですばやく見つけることができます。
ケルシー

1
残念ながら、それも間違った答えです。はい、これは本やMSDNで見つかるはずですが、MicrosoftのあるグループがMicrosoftの別のグループと話せず、すでに解決されている問題に対する劣った解決策を考え出した場合です。詳細については、blog.iswix.com / 2006/07 / msi-vs-net.htmlを参照してください。
Christopher Painter

9
@Christopher Painter 2k5以降、MSインストーラーを使用していますが、問題は発生していません。あなたがそれに同意し、それを「アンチパターン」と見なすかどうかは、この質問の要点ではありません。それは、xをyで行う方法であり、aをbで行う方法ではありません。私が質問を投稿したとき、それは文書化の目的でした。
ケルシー

3
その後、あなたは6年間幸運に恵まれてきました。:あなたが読みたいと思うかもしれませんrobmensching.com/blog/posts/2007/4/19/...
クリストファー・ペインター

1
あなたが得る場合はService name contains invalid characters, is empty, or is too long (max length = 80)インストーラを追加するときにエラーを右、再び灰色の領域をクリックし、プロパティに移動し、サービス名の値が設定されていることを確認してください。
wolfyuk 2015年

51

Kelseyの最初の一連の手順に従って、インストーラークラスをサービスプロジェクトに追加しますが、MSIまたはsetup.exeインストーラーを作成する代わりに、サービスを自己インストール/アンインストールします。以下は、開始点として使用できる私のサービスの1つからのサンプルコードです。

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
好奇心から、自己インストール/アンインストールサービスを利用するメリットは何ですか?サービスがそれ自体をインストールする場合、最初にどのようにサービスを開始して、最初にインストールできるようにしますか?サービスをインストールせずに開始するメカニズムがある場合、なぜそれをインストールする必要がないのですか?
カイリーナロ

3
@クリストファー-私はしません。私の解決策は、ソフトウェアの配布に使用するフルインストーラーの代わりにはなりません。無人のキオスクで組み込みPCを駆動するソフトウェアを作成する場合など、いくつかの状況で機能する別のオプションを紹介します。

4
本番マシンにインストールする場合は、必ず管理者として実行してください。/ iパラメータを使用してEXEファイルを呼び出すBATファイルを作成しましたが、管理者としてBATファイルを実行したにもかかわらず、本番環境では機能しませんでした。管理者としてコマンドラインプロンプトを開き、EXEファイル/ iを(BATファイルを使用せずに)明示的に呼び出す必要がありました。少なくとも、Windows Serverの2012で私に起こったこと
サンフランシスコGoldenstein

1
RE:コマンドラインに出力がありません。VS 2017 Communityを使用して、新しいサービスプロジェクトのデフォルトは出力タイプ:Windows Applicationおよびスタートアップオブジェクト:(none)でした。出力タイプをに変更しConsole Application、スタートアップオブジェクトを設定する必要がありましたmyservice.Program。気付かない影響があるかもしれない場合は、お知らせください。
ジョナサン

1
サンプルコードにタイプミスはありますか?3つの異なるサービス(CSMessageQueueService、MyService、MyQueueService)があるのはなぜですか?
Nils Guillermin

27

KelseyもBrendanソリューションも、Visual Studio 2015 Communityでは機能しません。

インストーラーでサービスを作成するための簡単な手順は次のとおりです。

  1. Visual Studioを実行し、 File->New->Project
  2. 「.NET Framework 4」を選択し、「インストールされたテンプレートの検索」で「サービス」と入力します。
  3. 「Windowsサービス」を選択します。名前と場所を入力します。押すOKます。
  4. Service1.csをダブルクリックし、デザイナーで右クリックして[インストーラーの追加]を選択します
  5. ProjectInstaller.csをダブルクリックします。serviceProcessInstaller1の場合は、[プロパティ]タブを開き、[アカウント]プロパティの値を[ローカルサービス]に変更します。serviceInstaller1の場合、「ServiceName」を変更し、「StartType」を「Automatic」に設定します。
  6. serviceInstaller1をダブルクリックします。Visual StudioがserviceInstaller1_AfterInstallイベントを作成します。コードを書く:

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
  7. ソリューションを構築します。プロジェクトを右クリックして、「ファイルエクスプローラーでフォルダーを開く」を選択します。bin \ Debugに移動します。

  8. 以下のスクリプトでinstall.batを作成します。

    :::::::::::::::::::::::::::::::::::::::::
    :: 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. uninstall.batファイルを作成します(pen-ult行/i/u
  10. サービスをインストールして開始するには、install.batを実行し、停止してアンインストールするには、uninstall.batを実行します。

14

VS2017の場合、 "Microsoft Visual Studio 2017 Installer Projects" VS拡張機能を追加する必要があります。これにより、追加のVisual Studio Installerプロジェクトテンプレートが提供されます。https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

Windowsサービスをインストールするには、新しいセットアップウィザードタイプのプロジェクトを追加し、Kelseyの回答https://stackoverflow.com/a/9021107/1040040の手順に従ってください。


1

InstallUtilクラス(ServiceInstaller)は、Windowsインストーラーコミュニティによってアンチパターンと見なされています。Windowsインストーラーがサービスの組み込みサポートを備えているという事実を無視するのは、壊れやすく、プロセスから外れた、ホイールの再発明です。

Visual Studioデプロイメントプロジェクト(Visual Studioの次のリリースでも同様に高く評価され、非推奨になっていません)は、サービスをネイティブでサポートしていません。しかし、それらはマージモジュールを消費する可能性があります。そこで、このブログ記事を見て、サービスを表現できるWindowsインストーラーXMLを使用してマージモジュールを作成し、VDPROJソリューションでそのマージモジュールを使用する方法を理解します。

WindowsインストーラーXMLを使用したInstallShieldの拡張-Windowsサービス

IsWiX Windowsサービスチュートリアル

IsWiX Windowsサービスビデオ


1
古いVisual Studioには、簡単に作成できるインストーラーを使用した展開プロジェクトがありました。サードパーティのソフトウェアコンポーネントを購入する必要がありますか?
Alexey Obukhov 2017

@AlexeyObukhov Wixは無料で使用できます。これはVS自体が使用しますが、Wixの問題はGitの問題とほぼ同じです-ほぼ垂直な学習曲線です。
アランB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.