2011-07-05 4 views
16

J'ai une erreur particulière où certains processus semblent parfois utiliser le presse-papiers lorsque mon application va gérer les opérations de copie de copie &. Il y a quelques tentatives de travail, et j'ai une solution acceptable en place, mais je voudrais localiser le processus si l'erreur se reproduit.Déterminez quel processus verrouille le presse-papiers

+0

Bien que je suis d'accord avec le sentiment de cette question, que feriez-vous exactement avec cette information? Même si cela était possible (et je ne suis pas sûr que ce soit le cas), il n'y a pas grand chose à faire avec la réponse. (Tuer le processus? Pas une chance!) –

+1

@mike Pouvez-vous mettre en place un message pour laisser l'utilisateur savoir? Cela pourrait être un processus sous le contrôle direct de l'utilisateur. – mickeyf

+0

@mickeyf Même si vous faites cela, que suis-je, l'utilisateur, supposé faire? _I_ n'a pas verrouillé le presse-papiers, et il n'y a rien que je puisse faire pour le déverrouiller, à moins de fermer le programme qui le verrouille (et, puisque j'essaie de faire mon travail, vous pouvez juste oublier ça). –

Répondre

18

J'ai enveloppé ma solution dans une méthode facile à utiliser (et quelques déclarations):

[DllImport("user32.dll", SetLastError = true)] 
static extern IntPtr GetOpenClipboardWindow(); 

[DllImport("user32.dll", SetLastError = true)] 
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); 

private static Process GetProcessLockingClipboard() 
{ 
    int processId; 
    GetWindowThreadProcessId(GetOpenClipboardWindow(), out processId); 

    return Process.GetProcessById(processId); 
} 

Profitez !

+2

Y at-il un moyen de bloquer le presse-papiers en connaissance de cause pour voir comment tout cela fonctionne? – toong

0

Pour diagnostiquer quelque chose comme cela, je suggère de commencer avec Process Explorer, http://technet.microsoft.com/en-us/sysinternals/bb896653

+0

Merci, mais ni moi ni les utilisateurs ont le temps de surveiller quelque chose comme ça. De toute façon, j'ai trouvé ce que je cherchais. –

+0

@RichardPianka: Si vous avez trouvé ce que vous cherchiez, partagez-le ici. SO est une rue à double sens. –

3

est ici une solution similaire, mais cela vous donne une chaîne que vous pouvez montrer à l'utilisateur:

[System.Runtime.InteropServices.DllImport("user32.dll")] 
static extern IntPtr GetOpenClipboardWindow(); 

[System.Runtime.InteropServices.DllImport("user32.dll")] 
static extern int GetWindowText(int hwnd, StringBuilder text, int count); 

private string getOpenClipboardWindowText() 
{ 
    IntPtr hwnd = GetOpenClipboardWindow(); 
    StringBuilder sb = new StringBuilder(501); 
    GetWindowText(hwnd.ToInt32(), sb, 500); 
    return sb.ToString(); 
} 
+0

Merci, je cherchais le nom du processus, mais c'est potentiellement plus utile pour les utilisateurs finaux. –

4

Sur la base de la réponse de Jeff Roe, mais montre comment obtenir la longueur du texte, donc pourrait être> 500. Aussi gère le cas où la fenêtre n'est pas trouvée.

[System.Runtime.InteropServices.DllImport("user32.dll")] 
static extern IntPtr GetOpenClipboardWindow(); 

[System.Runtime.InteropServices.DllImport("user32.dll")] 
static extern int GetWindowText(int hwnd, StringBuilder text, int count); 

[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern int GetWindowTextLength(int hwnd); 

private static string GetOpenClipboardWindowText() 
{ 
    var hwnd = GetOpenClipboardWindow(); 
    if (hwnd == IntPtr.Zero) 
    { 
     return "Unknown"; 
    } 
    var int32Handle = hwnd.ToInt32(); 
    var len = GetWindowTextLength(int32Handle); 
    var sb = new StringBuilder(len); 
    GetWindowText(int32Handle, sb, len); 
    return sb.ToString(); 
} 
Questions connexes