ずいぶん長い間ブログ放置してました…

言い訳すると、忙しかったんです。。


まぁ、それは置いといて。



タイトル通り、作ってみました。

(開発環境:Visual C#2008 Express Edition)


デバッガビジュアライザについては、以下を参考にどうぞ↓

http://msdn.microsoft.com/ja-jp/library/zayyhzts(v=VS.90).aspx



本来、デバッガビジュアライザを呼ぶときは、FormやControlしか引数に取らないのですが、今回はデバッガビジュアライザからWPFのWindowを呼んでやろうかと。

デバッグ対象は、DataSet等、つまり、DataSet VisualizerをWPFで作るだけという手抜き…


まぁ、最初からインストールされているDataSet Visualizerは、データが多いと表示されない部分があるので、そのバグは直しましたが。


次の順番で作りました。


1.WPF Toolkitのインストール

 どうしてもDataGridを使いたかったからです。というか、無いときついです。

 .NET Framework3.5で作ったので。


2.ビジュアライザを呼ぶ準備

 DialogDebuggerVisualizerを継承したり、DataViewをDataTableに変換してシリアル化するクラス作ったり、テスト用フォーム作ったりとか、いろいろです。

 以前、Controlクラスのデバッガビジュアライザ作ったことあったので、ここは楽でした。


3.データ表示クラスの作成

 WPFでUserControl作ってElementHost使ってFormに貼るか、WPFのWindowをFormから呼ぶか悩みました。


 …どっちもダメでしたが。


 何がダメかというと、デバッグ中にWPF呼ぶと、異様にメモリ使用量が増えるという…

 なぜか、20MBぐらいは使う上に、Visual C#閉じるまで開放してくれませんでした。

 (ElementHostに空のUserControl貼って、空のフォームに貼ったやつをデバッガから呼んでも5MBぐらい増えた)

 単にやり方が悪い気がしないでもないですが。



 というわけで、デバッガビジュアライザをDLLじゃなくて、EXEで作成するようにしました。


 こんな感じで呼び出します。


 //自身のパスを取得し、プロセス開始準備を行う

 ProcessStartInfo pInfo = new ProcessStartInfo(CommonUtility.AssemblyPath);


 pInfo.ErrorDialog = false;


 //「1」の場合はDataSet、「2」の場合はDataTable
 pInfo.Arguments = arg;


 pInfo.UseShellExecute = false;


 Process pro = Process.Start(pInfo);


 pro.EnableRaisingEvents = true;


 pro.Exited += (sender, e) => {
  //他プロセスから実行されるらしいので、コントロール所有スレッドで実行するよう指定する
  //ActionでもMethodInvokerでも一緒
  this.Invoke(new Action(this.Close));
 };


 WPF側の起動はこんな感じです。


/// <summary>
/// コマンドライン引数の受け取り
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Application_Startup(object sender, StartupEventArgs e) {
 if (e.Args.Length == 0) {


  this.Shutdown();


  return;


 } else {


  string arg = e.Args[0];


  //起動モードの設定
  if (arg == "1") {


   CommonUtility.Mode = ExecuteMode.DataSet;


  } else if (arg == "2") {


   CommonUtility.Mode = ExecuteMode.DataTable;


  } else {
   MessageBox.Show("コマンドライン引数が不正です。", "エラー");


   this.Shutdown();

   return;
  }
 }
}


4.exe間通信の方法


 ファイル使えば一発

 ↑じゃ面白く無いので、今回はIPCチャネルとかいうものを使ってみました。

 参考:http://msdn.microsoft.com/ja-jp/library/h9ew6576(v=VS.90).aspx

 が、ダメ。

 

 どうやっても、クライアント側(今回で言えばWindowを持ってるexe)でデバッグ対象の型付きデータセットを解釈してくれず…逆シリアル化できないと怒られること数十回。

 (アセンブリが見つからないと例外が起こる。そもそもexeから型参照してないからあるわけがない。byte配列にしても怒られた)


 諦めて、ファイルを受け渡しするようにしました。Diffgramでデータを切りだして、スキーマも別ファイルで切り出せば、デバッグ直前のDataSetの中身を再現できますね。




とまぁ、「exeを使うこと」と「ファイルでexe間のやりとりを行う」ことが決まったので、一からソリューションを作り直しました。

ちなみに、4だけで2週間近く止まりました。。




完成形はこちら。


1.呼び出し前



新米プログラマーのひとりごと



2.ビジュアライザ表示


新米プログラマーのひとりごと


見た目とか二の次だったので、WPFっぽくないですね…

実用化目指しているので、これから機能面は凝りたいと思います。



よい勉強となりました。




追記:インデント、効かないんだね…