Domanda

Sto usando il seguente codice per copiare il testo negli appunti:

  Clipboard.Open;
  try
    Clipboard.AsText := GenerateClipboardText;
  finally
    Clipboard.Close;
  end;

apparentemente a caso ottengo "Impossibile aprire appunti: Accesso negato" errori. Sto indovinando che questi errori sono causati da altre applicazioni di blocco degli appunti, ma non ho mai sembrano fare qualsiasi cosa con altre applicazioni che dovrebbe causare le serrature.

Stranamente i miei utenti sembrano essere la segnalazione più degli errori con Vista e Windows 7 che con XP.

C'è un modo per verificare se gli appunti è bloccata prima di tentare di accedervi?

È stato utile?

Soluzione

Questo non è un problema di Delphi. Perché negli appunti può essere bloccato da un momento all'altro, anche se si controlla, se gli appunti non è attualmente bloccato, potrebbe diventare bloccato subito dopo il controllo.

Hai due possibilità qui:

  1. Non utilizzare la classe appunti Delphi. Invece di utilizzare le funzioni API prime, cui sia possibile controllare un po 'più a grana fine su eventuali situazioni di errore.
  2. Aspettatevi il codice a fallire con l'aggiunta di un gestore di eccezioni. Poi aggiungere un po 'di codice di tentativi, cioè Riprova per impostare il testo per tre volte, magari con backoff esponenziale, prima di gettare il proprio errore.

io consiglierei la seconda soluzione, perché sarebbe l'approccio più Delphi-like e alla fine si tradurrà in codice più pulito.

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;

Altri suggerimenti

  

Stranamente i miei utenti sembrano essere   segnalazione più degli errori con   Vista e Windows 7 che con XP

Questo può avere a che fare con il modo in Vista / Win7 che fare con la notifica visualizzatore di appunti. Mentre continuano a sostenere la "catena spettatore appunti" XP, che invia un messaggio di notifica che deve essere re-inviato a ciascun ascoltatore, a sua volta (e se un app non riesce a fare questo, le altre applicazioni non sono notificati). A partire da Vista, le applicazioni vengono comunicate direttamente. E non c'è niente per impedire loro di tentare di accedere al clipboard tutto in una volta.

Analogia: Ho 3 figli. Ho una torta. Con le regole di XP, ho dire al figlio maggiore di avere qualche torta, poi dire il prossimo figlio maggiore di avere una fetta. Lei ottiene la sua fetta, dice il fratello, ottiene la sua, e racconta suo fratello, che ottiene il suo, e tutto procede in modo ordinato.
Problema:. Il figlio di mezzo prende la torta nella sua stanza, non dice il più giovane, e che esce fuori più giovani

Con Vista / Windows7, quel sistema esiste ancora. Ma le applicazioni più recenti possono richiedere di essere avvisato immediatamente, da me, non appena la torta arriva in cucina. Grido "torta è pronta!" e tutti si presentano allo stesso tempo e cercare di afferrare un po '. Ma c'è solo uno che serve coltello, in modo da avere per mantenere raggiungere per il coltello, non riuscendo a farlo, e in attesa della prossima occasione.

Non v'è alcun modo per verificare la presenza di qualcosa e poi a seconda del risultato fare qualcosa di diverso con l'aspettativa che non poteva fallire, perché a meno che il controllo e l'azione sono un'operazione atomica c'è sempre la possibilità che un altro processo o thread fa lo stesso in parallelo.

Questo vale se si tenta di aprire la clipboard, aprire un file, creare o eliminare una directory - si dovrebbe semplicemente provare a farlo, forse più volte in un ciclo, e con grazia gestire gli errori

.

Prova a controllare GetClipboardOwner, se non è nullo e non il tuo Application.Handle, non è possibile aprire modificare il suo contenuto.
E anche mi sembra bene ad andare, potrebbe non essere più quando si effettivamente farlo.
Quindi aggiungere una prova se non in un ciclo fino ad ottenere o rinunciare piacevolmente (avvisare l'utente per esempio).

Prima di tutto si prega di notare che questo probabilmente non è un problema nell'applicazione. Altre applicazioni bloccate negli appunti o incasinato la catena di notifica e ora l'applicazione non riesce ad accedervi. Quando mi hanno problemi di questo tipo mi riavviare il computer e che magicamente andare via ... beh ... almeno fino a quando ho eseguire nuovamente l'applicazione che crea il problema.

Questo codice (non controllato in Delphi) può aiutarvi. Non risolverà il problema è la catena di notifica è rotto (nulla se non un riavvio del PC potrà mai risolvere il problema), ma risolverà il problema se un'applicazione sta chiudendo negli Appunti per un po '. Aumentare i MaxRetries se tale applicazione fastidioso mantiene appunti bloccato per un tempo molto lungo (secondi):

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;

Inoltre, può essere una buona idea di abbandonare il 'rilancio' e convertirlo in una funzione e usare in questo modo:

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.');

Credo che si esegue la vostra applicazione su Win 8 o superiore.

Basta fare clic destro sul file .exe App, vai alla scheda Compatibilità e la modalità di compatibilità cambiamento su Windows XP o versioni inferiori. Funzionerà, garantite!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top