PrintDialog.UseEXDialog を true にすると「この操作の実行中にエラーが発生しました。」が起きる
PrintDialog.UseEXDialog を true にすると「この操作の実行中にエラーが発生しました。」が起きる
コンソールアプリケーションでプリンター選択ダイアログが表示できません。
結論から言うと、解決するにはコンソールアプリケーションではなく Windows アプリケーションで作り直す必要があります。
状況
プリンター選択ダイアログを表示しようとすると、一瞬だけ表示された後、印刷エラーのメッセージが出る状況です。
プリンター選択ダイアログを出さなければ、印刷はできます。
コードで言うと PrintDocument.Print()
はできるが、PrintDialog.ShowDialog()
はエラーになります。
関係あるかどうかは不明ですが、ターゲットフレームワークは .NET 6.0 にしています。
原因
どうやら PrintDialog.UseEXDialog プロパティが true だと悪さをするようです。
UseEXDialog プロパティが true になっているときだけ、プリンター選択ダイアログの表示エラーが起きました。
ちなみにエラーではあるが、あくまでダイアログ側のエラーです。
メッセージボックスを閉じた後は後続の処理に移ります。
戻り値は Cancel だったので、キャンセルボタンがクリックされたのと同じ扱いとなるようです。
プログラム側では例外も何も起きないので、このエラーを検知するのはおそらく無理かと。
var doc = new System.Drawing.Printing.PrintDocument();
var dialog = new System.Windows.Forms.PrintDialog();
dialog.Document = doc;
// ここで true にすると悪さをする模様
dialog.UseEXDialog = true;
// ダイアログ表示
// 一瞬だけ表示され、その後、印刷エラーのメッセージボックスが出る
var dialogResult = dialog.ShowDialog();
// メッセージボックスを閉じるとここに処理が移る(例外は起きない)
System.Diagnostics.Debug.WriteLine($"DialogResult={dialogResult}");
32bit でビルドすれば動く??? (…解決しなかった、失敗)
64bit で動かしたときにエラーになる、という情報を仕入れたので 32bit にしてみたがダメでした。
プラットフォームを Any CPU から x86 に変えたところ、ダイアログの表示で異常終了しました。
起きたエラーはメモリアクセス違反でした。
System.AccessViolationException
HResult=0x80004003
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=<例外のソースを評価できません>
スタック トレース:
<例外のスタック トレースを評価できません>
解決策(暫定)
UseEXDialog プロパティを false にします。
false にすることで、ダイアログが Windows XP スタイルで表示されなくなりますが、ダイアログ自体が出ないよりはマシではないかと。
(Windows XP スタイルでなくなることの影響は、いずれ調べないといけませんが)
解決策(推奨)
アプリケーションの種類を「コンソールアプリケーション」→「Windows アプリケーション」に変更します。
これだけで表示されるようになります。
UseEXDialog プロパティを false にして逃げるより、こちらの方が無難でしょう。
ちなみに、印刷機能を Windows アプリケーションのクラスに実装して、コンソールアプリケーションからプロジェクト参照で呼び出すのはダメでした。
スタートアップが Windows アプリケーションでないと、XP スタイルでのプリンター選択ダイアログは表示できないってことですかね。
アカウントを作成 して、もっと沢山の記事を読みませんか?
この記事にコメントをしてみませんか?