OITA: Oika's Information Technological Activities

@oika 情報技術的活動日誌。

C# Clipboardクラスでクリップボードを監視するとComExceptionが発生する

先日公開したぺたこーだというソフトで
クリップボードにコピーされた文字列をリアルタイムで画面表示する処理を
入れていたんだけど、似たようなツールを作って仕事で使っていたら、
ときどきComExceptionをはいて落ちることがあった。

クリップボード監視処理は以下のような感じ。

var data = Clipboard.GetDataObject();  
if (data.GetDataPresent(DataFormats.Text)) {  
    var text = data.GetData(DataFormats.Text) as string;  
}  

これを短い間隔でループさせてた。

んで、たまに0x800401D0(CLIPBRD_E_CANT_OPEN)の
ComExceptionが出るのは前からわかっていて、
どうやら他プロセスで専有してるときにアクセスしようとして
クリップボードが開けないことがあるらしいぞと。
それはまあいいやと思って無視してたんだけど、
それだけじゃなくて、どうもVisualStudio上とかExcel上とかで
コードをコピーしたタイミングとかち合った場合に、
0x80040064(DV_E_FORMATETC)のCOMExceptionが出ることがあるようだった。

んで、そもそもなんだけど、とりあえず↑のコードのように
GetDataObject()したやつからGetDataPresent()してGetData()ってのは
.NET 2.0以前のあほほど古い書き方らしいことに気づき、
Clipboard.GetText()を使う書き方に直した。
それでVisualStudio上のコピーではCOMExceptionが出なくなった(たぶん)。
しかし、相変わらずExcel上のコピーは解決せず。

ググったら、クリップボードに遅延レンダリングする処理と監視とが
かち合うとあかんというような情報を発見。
のぶろぐ クリップボード使用時のCOMException

COMExceptionはすべからく無視だ!とおっしゃってるので
同じように無視してみることにしましたとさ。