web-dev-qa-db-ja.com

C#カスタムインストーラークラスのデバッグ

インストーラーを拡張し、afterInstallをオーバーライドするインストールクラスを作成しましたが、nullポインター例外が発生します。クラスのデバッグを行うにはどうすればよいですか?

27
Deano

コードのセクションをデバッグするのが難しい場合に便利なものは次のとおりです。

System.Diagnostics.Debugger.Break()

インストールされているデバッガー(VStudio、WinDbg、リモートデバッガーなど)によってキャッチされたブレークポイントをスローします。

これを使用して、通常のF5 + Goまたは「プロセスへの接続」を実行するのが困難または不可能な非常にトリッキーな領域をデバッグします。

  • 短期間のプロセス
  • 時間に敏感なプロセス
  • 生成されたサブプロセスに侵入する
  • インストーラー
  • サービスの停止/開始
  • 分散システム
43
stephbu

私が見つけた最善の方法は、単体テストを作成し、単体テストからインストーラークラスを新規作成して初期化することです。

[TestClass] public class InstallerTest {
[TestMethod]
public void InstallTest() {
  // substitute with your installer component here
  DataWarehouseInstall installer = new DataWarehouseInstall();

  string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

  string installLogFilePath = Path.Combine(assemblyDirectory, "install.log");
  installer.Context = new System.Configuration.Install.InstallContext(installLogFilePath, null);      

  // Refactor to set any parameters for your installer here
  installer.Context.Parameters.Add("Server", ".");
  //installer.Context.Parameters.Add("User", "");
  //installer.Context.Parameters.Add("Password", "");
  installer.Context.Parameters.Add("DatabaseName", "MyDatabaseInstallMsiTest");
  //installer.Context.Parameters.Add("DatabasePath", "");

  // Our test isn't injecting any save state so we give a default instance for the stateSaver
  installer.Install(new Hashtable());
} }

少なくとも、IDEツールの方が優れています。これは、多数のコンポーネントを使用する非常に大規模なインストーラーに特に役立ちます。次に、順序付けられた単体テストを作成し、それらを順番に実行して、デバッグ中または自動ビルド中のインストーラー。

もう1つのヒントは、一般的なSOLID/GRASSソフトウェアの原則です...きちんとした/薄いレイヤーで開発し、実際の「カスタムアクション」インストーラーロジックを非常にシンプルに保ち、代わりにインストーラーに固有の再利用可能なAPIを呼び出します。 、UI開発に慣れているように。 (とにかく、インストーラーは単なる別のUIです。)これは、製品のすべてのインストーラー間で特定のUIエクスペリエンスを共有することが目標である場合に特に重要です。

10
Timex

誰も実際に答えていないことに驚いた。 MessageBox.Show( "hello")をカスタムアクションのInstall()メンバーに配置します。 debugconfigでデプロイメントをビルドします。インストール。メッセージボックスが表示されたら、VS IDE、デバッグ、接続プロセスに移動し、「管理対象」というラベルの付いたmsiexecのインスタンスを探します。デバッガーをmsiexecのそのインスタンスに接続します。次に、カスタムアクションのソースに戻り、MessageBox.Show()の呼び出しの直後にブレークポイントを設定します。メッセージボックスを閉じると、ブレークポイントがヒットし、IDEでデバッグします。

10
Bob Denny

インストーラープロセスを[デバッグ]-> [プロセス]-> [アタッチ]でVisualStudioにアタッチするか、CTRL + ALT + Pでブレークポイントを設定すると、次のことができるようになります。

4
Oscar Cabrero

インストーラーメソッドにDebugger.Launch()ステートメントを追加します。これにより、「Visual Studioジャストインタイムデバッガー」が起動し、Visual Studioのインスタンスをアタッチしてインストーラークラス(MSI)をデバッグできます。これは、Visual Studio2010でも機能するはずです。ただし、これを行うには管理者権限が必要です。管理者権限がない場合は、問題が発生する可能性があります。したがって、MSIをデバッグするための管理者としてログインします。例えば:

public override void Install(System.Collections.IDictionary stateSaver)
{
    Debugger.Launch();
    base.Install(stateSaver);

}

Visual Studio 2005では、Debugger.Break()でさえ機能しますが、どういうわけかこれはVisual Studio2010では機能しません。

3

EventLog.WriteEntry( "source"、 "message")を使用し、インストール時にEventLogを確認します。おそらく最適ではありませんが、私にとってはうまくいきます:)

1
Thomas

上記のどれも私のために働いていませんでした。これが実際に機能したものです。 「両方」の行を挿入する必要があることに注意してください。

using System.Diagnostics;

MessageBox.Show("Test is about to begin");
Debugger.Launch();

デバッグするメソッドの先頭に次のコードを記述します

#if DEBUG
MessageBox.Show(Process.GetCurrentProcess().Id.ToString());
#endif

したがって、メソッドが呼び出されると、上記のコードがヒットし、上記のプロセスIDを使用してデバッガーをプロセス(ctrl + alt + p)にアタッチできます。昇格された権限でVSを開始する必要がある場合があります。

1
Adith

次のクラスを使用して、単純なログをターゲットディレクトリに書き込みます。私の意見では、VisualStudioデバッガーを使用するよりも簡単です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MyCompany.Deployment
{
    /// <summary>
    /// Enables a quick and easy method of debugging custom actions.
    /// </summary>
    class LogFile
    {
        const string FileName = "MyCompany.Deployment.log";
        readonly string _filePath;

        public LogFile(string primaryOutputPath)
        {
            var dir = Path.GetDirectoryName(primaryOutputPath);
            _filePath = Path.Combine(dir, FileName);
        }

        public void Print(Exception ex)
        {
            File.AppendAllText(_filePath, "Error: " + ex.Message + Environment.NewLine +
                    "Stack Trace: " + Environment.NewLine + ex.StackTrace + Environment.NewLine);
        }

        public void Print(string format, params object[] args)
        {
            var text = String.Format(format, args) + Environment.NewLine;

            File.AppendAllText(_filePath, text);
        }

        public void PrintLine() { Print(""); }
    }
}
1
Wayne Bloss

ロギングの目的(3.5)では、以下を使用するのはどうですか?

Context.LogMessage("My message");
1
Almund

InstallUtil.exeユーティリティを使用して、インストーラコンポーネントをテストすることもできます。

インストーラークラスでac#クラスアセンブリを作成した場合は、デバッグ設定を変更して外部プログラム 'C:\ Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe'を起動し、それに応じてコマンドライン引数を入力します(例:/Args = myargument "アセンブリへのパス")

最後にブレークポイントを設定したら、f5キーを押すと、コードをデバッグする準備が整います。 -視差

1
Mario Topf

これが実際に私のために働いたものです。

System.Diagnostics.Debugger.Launch();

次に、インストーラープロジェクトを右クリックして、[インストール]を押します。

0
Ahmed Sabry

.csprojまたは.csproj.userファイルに次のセクションを追加することで、インストーラープロジェクトのデバッグを自動化できます。

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <StartAction>Program</StartAction>
  <StartProgram>$(MSBuildBinPath)\installutil.exe</StartProgram>
  <StartArguments>$(AssemblyName).dll</StartArguments>
</PropertyGroup>

他の開発者がこの変更の恩恵を受けたい場合はプロジェクトファイルを使用し、自分で使用したい場合は.userファイルを使用します。

0
Peter

vMを構築し、Visual Studioをインストールし、そのコピーを作成して(または、差分仮想HDDを作成して)、VMの下のデバッガーでインストーラーを実行します。

それが私がすることです(しかし私は専門家ではありません)。

0
BCS