Visual Studio での単純なデバッグ方法は…
VisualStudioでは、アプリケーションのプロジェクトをスタートアッププロジェクトに設定して、「開始」するだけでデバッグを行うことができます。
また、プロジェクト設定からデバッグ実行時のコマンドライン引数を設定することができます。
単純なデバッグはこれでOKですが、コマンドライン引数の値を頻繁に変えたいような場合は、ここを都度メンテしてデバッグを行うのは面倒です。
コマンドライン引数のデバッグを楽にするには…
コマンドライン引数を、様々な入力(画面入力/外部ファイル/ハードコーディング/etc…)で実行できれば楽です。そのためのテスト用プロジェクトを作成します。
テスト用プロジェクトでは、コマンドライン引数を任意の入力から構築して、デバッグしたいコンソールアプリケーションを実行します。
今回はデバッグを行うことが目的なので、エントリーポイント(Mainメソッド)を直接呼び出して実行してみます。
Mainメソッドが他プロジェクトからアクセス可能であれば、単純に呼び出せばよいのですが、アクセス不可の場合そうもいきません。基本的に公開する意味がないので、アクセス不可の場合がほとんどだと思います。
そのため、今回はアクセス不可の場合を想定してリフレクションを利用して呼び出してみます。
サンプルコード
C#
using System; namespace ConsoleApp { class Program { static void Main(string[] args) { foreach(string arg in args) { Console.WriteLine(arg); } } } }
using System; using System.Collections.Generic; using System.Windows.Forms; namespace ConsoleAppTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void execute_Click(object sender, EventArgs e) { string[] arguments = buildArguments(); //For Non Public System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(@"..\..\..\ConsoleApp\bin\Debug\ConsoleApp.exe"); assembly.EntryPoint.Invoke(null, new object[] { arguments }); } private string[] buildArguments() { List<string> arguments = new List<string>(); arguments.Add("arg1"); arguments.Add("arg2"); return arguments.ToArray(); } } }
VB.NET
Public Module ConsoleAppVB Public Sub Main(ByVal args As String()) For Each arg As String In args Console.WriteLine(arg) Next End Sub End Module
Public Class Form1 Private Sub execute_Click(sender As Object, e As EventArgs) Handles execute.Click Dim arguments As String() = BuildArguments() 'For Non Public Dim assembly As Reflection.Assembly = Reflection.Assembly.LoadFrom("..\..\..\ConsoleAppVB\bin\Debug\ConsoleAppVB.exe") assembly.EntryPoint().Invoke(Nothing, New Object() {arguments}) 'For Public ConsoleAppVB.ConsoleAppVB.Main(arguments) End Sub Private Function BuildArguments() As String() Dim arguments As New List(Of String) arguments.Add("arg1") arguments.Add("arg2") Return arguments.ToArray() End Function End Class
コードの解説
Assemblyの読み込み
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(@"..\..\..\ConsoleApp\bin\Debug\ConsoleApp.exe");
デバッグビルドしたコンソールアプリケーション配置パスを指定して、アセンブリを読み込みます。ここでは、対象プロジェクトのビルド出力パスを指定しています。
Mainメソッドの呼び出し
assembly.EntryPoint.Invoke(null, new object[] { arguments });
Mainメソッドのオブジェクトは、読み込んだAssmebly.EntryPointで取得することができます。
Invokeで実行します。
第1引数は、メソッドを呼び出すインスタンスを指定します。
今回ように静的メソッドの場合はnullを指定します。
第2引数は、呼び出しメソッドの引数をObject配列で引き渡します。
今回の場合、コマンドライン引数(String配列)1つを引数に持つメソッドのため、String配列1つを要素に持つObject配列を引き渡します。
今回のサンプルではハードコーディングでコマンドライン引数を構築していますが、ここを画面値から取得するなり分岐をかけてやるなりすれば、多少手軽にデバッグが行えるようになると思います。
おわりに
あまり調べても期待する情報が出てきませんでしたが、一般的なやり方ってどうなのでしょう。