2011-07-05 27 views
16

Tengo un error peculiar en el que, ocasionalmente, parece que algún proceso está utilizando el portapapeles cuando mi aplicación va a manejar operaciones de pegar copia &. Hay algunos intentos de reintentos, y tengo una solución aceptable, pero me gustaría ubicar qué proceso es si el error vuelve a ocurrir.Determine qué proceso está bloqueando el portapapeles

+0

Aunque estoy de acuerdo con el sentimiento de esta pregunta, ¿qué harías exactamente con esta información? Incluso si esto fuera posible (y no estoy seguro), no hay mucho que puedas hacer con la respuesta. (¿Matar el proceso? ¡No es una oportunidad!) –

+1

@mike ¿Podría poner un mensaje para avisarle al usuario? Podría ser un proceso bajo el control directo del usuario. – mickeyf

+0

@mickeyf Incluso si haces eso, ¿qué soy yo, el usuario, se supone que debo hacer? _I_ no cerré el portapapeles, y no hay nada que pueda hacer para desbloquearlo, salvo cerrar cualquier programa que esté bloqueándolo (y, como estoy tratando de hacer mi trabajo, puedes olvidarte de eso). –

Respuesta

18

me he envuelto mi solución en un método fácil de usar (y algunas declaraciones):

[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); 
} 

Disfrute !

+2

¿Hay alguna manera de bloquear el portapapeles a sabiendas para ver cómo funciona todo esto? – toong

0

Para diagnosticar algo como esto Yo sugeriría comenzando con el explorador de procesos, http://technet.microsoft.com/en-us/sysinternals/bb896653

+0

Gracias, pero ni yo ni los usuarios tenemos tiempo para monitorear algo así. De todos modos, encontré lo que estaba buscando. –

+0

@RichardPianka: si encontraste lo que estabas buscando, compártelo aquí. SO es una calle de dos vías. –

3

he aquí una solución similar, pero esto le da una cadena se puede mostrar al usuario:

[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

Gracias, estaba buscando el nombre del proceso, pero eso es potencialmente más útil para los usuarios finales. –

4

Sobre la base de la respuesta de Jeff Roe, pero muestra cómo conseguir la longitud del texto, por lo que podría ser> 500. También maneja el caso donde no se encuentra la ventana.

[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(); 
} 
Cuestiones relacionadas