どうしたらいいです"ときのクリップボード:アクセスを否定"誤?
-
13-09-2019 - |
質問
私は、以下のコードへのコピーをテキストのクリップボード:
Clipboard.Open;
try
Clipboard.AsText := GenerateClipboardText;
finally
Clipboard.Close;
end;
一見ランダムで取得します"ときのクリップボード:アクセス拒否"。私は推測することによる誤差による他のアプリケーションのロックのクリップボードが、僕は見ている他のアプリケーションする必要があるのロックを解除します。
不思議と私のユーザーにも報告されることにより誤Vista、Windows7以上とさい。
があるので、チェックがクリップボードがロックされる前にアクセスしようとしているのですか?
解決
このデ問題です。がクリップボードにロックすることができた場合でも、チェックの場合、クリップボードが現在ロックされていないので、もってロック直後はチェックを外してください。
しての可能性はこちら
- なにDelphiのクリップボードクラスです。代わりに使用原API機能までもう少し対するきめ細かい制御が可能になっているエラーです。
- ことを期待コードが追加により例外ハンドラです。その追加コードリトライする再試行のテキスト、おそらく指数バックオフ、投げ独自のエラーになります。
でおすすめの第二ソリューションでもありませんし、デルフィ-のようにアプローチの結果とクリーナーコードです。
while not Success do
try
//Set the clipboard
Success := True;
except
on Exception do
begin
Inc(RetryCount);
if RetryCount < 3 then
Sleep(RetryCount * 100)
else
raise MyException.Create('Cannot set clipboard');
end;
end;
他のヒント
不思議な私のユーザーがあるように見えます とエラーの多くを報告します VistaとXPよりもWindows 7の
これは、ビスタ/ Win7のは、クリップボードビューアの通知に対処する方法で行う必要があります。彼らはまだ順番に各リスナーに再送信する必要があります1つの通知メッセージを送信XP「クリップボードビューアチェイン」を、サポートしていますが(1つのアプリがこれを行うに失敗した場合や、他のアプリには通知されません)。ビスタ以降では、アプリケーションが直接通知されます。そして、すべてを一度にクリップボードにアクセスしようとしているからそれらを保つためには何もありません。
類推:私は3人の子供を持っています。私がケーキを持っています。 XPのルールでは、私はその後、いくつかのケーキを持っているスライスを持って次に古い子供を伝えるために、最も古い子供に伝えます。彼女は彼が彼を取得し、彼女の兄に伝え、彼女のスライスを取得し、整然と彼の彼を取得弟、およびすべての進行を伝えます。
問題:真ん中の子最年少を教えてくれない、彼の部屋にケーキを取り、最年少はアウトミス
ビスタ/ Windows7のでは、そのシステムがまだ存在しています。しかし、新しいアプリケーションは、すぐにケーキが台所に到着すると、私が、すぐに通知されるように要求することができます。私は、「ケーキの準備ができている!」叫びますそれらはすべて同じ時間に現れ、いくつかをつかむしようとします。しかし、そこにナイフを提供するだけですので、彼らはそれを得るために失敗し、次の機会を待って、ナイフに手を伸ばす維持する必要があります。
何かして、その結果に応じて、かどうかを確認する方法はありませんチェック、アクションは1つのアトミック操作されない限り、可能性という別のプロセスやスレッドが常にあるので、それは失敗することができなかったことを期待して何かをやります同じことが、並行して行います。
これは、クリップボードを開いてファイルを開き、ディレクトリを作成または削除しようとするかどうかを保持している - 。あなたは、単にループで、多分数回それをやろう、と優雅にエラーを処理する必要があります。
それはあなたのApplication.Handle nullではないとされていない場合、あなたはそれがコンテンツです変更する開くことができない、GetClipboardOwnerをチェックしてみてください。
でもあなたが実際にそれを行うとき、それはもうないかもしれない、行ってもいいようです。
あなたはそれを得るか、きれいに(例えばユーザに通知)あきらめるまで、だから、ループを除い試みを追加します。
まず第一に、これはおそらく、あなたのアプリケーションでの問題ではないことに注意してくださいしてください。他のアプリケーションがクリップボードをロックしたり、通知のチェーンを台無しにし、今、あなたのアプリケーションがそれにアクセスするために失敗しました。私はこのような問題を持っているとき、私は、コンピュータを再起動すると、彼らは魔法のように私は再び問題を作成するアプリケーションを実行し、少なくともまでは...よく...離れて行くます。
このコード(Delphiでチェックされていない)があなたを助けるかもしれません。これは、問題は(PCの再起動を除いて何が今までそれを修正しません)通知チェーンが壊れているが、アプリケーションがしばらくの間、クリップボードをロックしている場合、それは問題を修正する修正されません。その厄介なアプリケーションは本当に長い時間のためにロッククリップボードを続ける場合MaxRetriesのを増やします(秒):
procedure Str2Clipboard(CONST Str: string; iDelayMs: integer);
CONST
MaxRetries= 5;
VAR RetryCount: Integer;
begin
RetryCount:= 0;
for RetryCount:= 1 to MaxRetries DO
TRY
inc(RetryCount);
Clipboard.AsText:= Str;
Break;
EXCEPT
on Exception DO
if RetryCount = MaxRetries
then RAISE Exception.Create('Cannot set clipboard')
else Sleep(iDelayMs)
END;
end;
また、それは「昇給」をドロップすると、関数に変換し、このようにそれを使用するのは良い考えかもしれます:
if not Str2Clipboard
then Log.AddMsg('Dear user, other applications are blocking the clipboard. We have tried. We really did. But it didn''t work. Try again in a few seconds.');
私はあなたが勝つ8以降でアプリケーションを実行していると思います。
ただ、Windows XPまたは下位バージョンの互換性]タブと変更互換モードに行き、あなたのアプリケーションの.exeファイルを右クリックします。それがうまくいく保証!