混乱を避けるために、System.Drawing はASP.NET およびサービスの下で動作しますが、サポートされていません。高負荷 (管理されていないリソースの不足)、メモリまたはリソースのリーク (適切に実装されていない、または破棄パターンと呼ばれる)、および/または表示するデスクトップがないときにダイアログがポップされるという問題が発生する可能性があります。
テストは後者を処理し、監視は前者を警告します。ただし、問題が発生した場合は、PSS に電話して修正を依頼できるとは思わないでください。
それで、あなたのオプションは何ですか?完全にサポートされたルートが必要なく、極端な負荷が予想されない場合は、多くの人が MSDN の警告を無視して System.Drawing を使用して成功しています。それらのいくつかは噛まれましたが、失敗談よりも多くの成功談があります.
何かをサポートしたい場合は、インタラクティブに実行しているかどうかを知る必要があります。個人的には、非インタラクティブなフラグをどこかに設定するのは、おそらくホスティング アプリに任せるでしょう。結局のところ、アプリは、ホストされた環境にあるかどうか、および/または GDI+ の問題を危険にさらしたいかどうかを判断するのに最適な位置にあります。
しかし、環境を自動的に検出したい場合は、SOでサービスのためにここで提供されるよりも悪い答えがあると思います。要約すると、EntryAssembly をチェックして ServiceBase から継承されているかどうかを確認するか、System.Console にアクセスしてみてください。ASP.NET の場合も同様に、HttpContext.Current を検出するだけで十分です。
私はデスクトップを探すための管理された方法または p/invoke の方法があると思います (これは本当にこれらすべての決定的な要因だと思います) および/または AppDomain からあなたの手がかりになる何か. しかし、私は '私はそれが何であるかわからず、MSDN はそれについて啓発的ではありません。
編集: MSDN をトローリングして、ここで重要なのは実際には (デスクトップをホストする) Window Stationであることを思い出しました。その情報を使用して、現在のウィンドウ ステーションへのハンドルを返すGetProcessWindowStation()を見つけることができました。そのハンドルをGetUserObjectInformation()に渡すと、デスクトップが表示されている場合、WSF_VISIBLE を持つ dwFlags を持つ必要があるUSEROBJECTFLAGS構造体が取得されます。
または、EnumWindowsStationsを使用すると、確認できるステーションのリストが表示されます。WinSta0 はインタラクティブなステーションです。
しかし、ええ、私はまだアプリにプロパティなどを設定させる方がはるかに簡単だと思います....
再度編集: 7 年後、MSが上で説明した正確な GetProcessWindowStation ダンスを実行するEnvironment.UserInteractiveに手がかりを得る..ホスティング アプリに委任することをお勧めします (彼らはもっと速くしたいかもしれませんが、少しだけ)よりリスクの高い System.Drawing パス) ですが、UserInteractive は、自分でピンボークせずに使用するのに適したデフォルトのようです。