keyhacとExcelの干渉を回避

 大変便利なkeyhacですが、常駐した状態でExcelでクリップボード操作(*1)をすると、そこそこの確率で以下のエラーが発生します。

クリップボードを空にできません。別のアプリケーションがカライップボードを使用している可能性があります。

クリップボードを開くことができません。

 どうも双方のクリップボードの処理が干渉しているようです。keyhacはWindows版のVer.1.77です。

(*1)選択したセルをマウスでドラッグした時や、[Ctrl]+[C]でコピーした時など、クリップボード操作をした時等


■ 原因(状況)の調査

 何が起こっているのか、誰が悪いのか、犯人探しをしたい訳ではないのだけれど、原因がわからないと直しようがない訳で、色々と調査したところ、以下の事がわかりました。

(a) Excelでコピー操作をすると、WM_CLIPBOARDUPDATEが複数回飛んでくる
(b) WM_CLIPBOARDUPDATEが飛ぶ度にGetClipboardSequenceNumberの値が更新される
(c) keyhacはOpenClipboard/GetClipboardData/CloseClipboardでデータを取得している
(d) クリップボードに、同時アクセスする事はできない (排他利用)

 この事から、Excelは複数回に分けてクリップボードを操作しており、以下のように2回目以降の処理がKeyhacの処理とバッティングしている可能性があります。

(1) Excel 1回目のクリップボード操作
(2) WM_CLIPBOARDUPDATE 発生
(3) keyhac OpenClipboard で排他アクセスを開始
(4) Excel 2回目のクリップボード操作 → 失敗
(5) Excelエラーメッセージを表示


■ 回避策

 Excelに手を入れる事はできないので、keyhacでなんとかする事にし、以下の2案を考えました。

(a) Excelがアクティブな時、クリップボード監視を中断する
(b) クリップボードからデータを取得するタイミングを遅延させる

 ざっと試したところ、(b)の方が良さそうだったのでこちらを採用しました。keyhacで該当の処理は「keyhac_clipboard.py」の「cblister_ClipboardHistory」クラスにあります。

keyhac_clipboard.py

 なんかdelayedCallが利用されていた痕跡があったので、これを再利用し、遅延時間を100msに修正する事にします。残念ながらkeyhacの開発環境がないので、メソッドを動的に入れ替えるという技を使います。

この fix_clipboard.py をextensionフォルダに保存します。

config.pyに

import fix_clipboard

の行を追加します。(importの並びの最後にでも追加してください)

※※※ この方法はkeyhacのバージョンに依存します (Ver.1.77専用) ※※※
※※※ 改良版が存在します ※※※

■ 結果

 とりあえず、当方の環境ではエラーが激減しました。稀に起きる事もあるのですが、そもそも排他リソースなので完全に無くす事はできないと思います。
 また、副作用として、コピー操作のちょうど100ms程度後に別のコピー操作をすると100%エラーが発生するようになります。狙ってできる事ではいと思いますが、遅延で回避するという事はそうゆう事です。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

この記事へのトラックバック

  • keyhacとExcelの干渉を回避の改良

    Excerpt:  前回のブログをtweetしたら作者に「いいね」されてびびってるのは私だよ。 Weblog: Jin/Gy-Oのブログ racked: 2018-05-22 21:45