Como verificar qual aplicativo tem a área de transferência?

7

Estamos implantando algumas máquinas virtuais com software de robôs que executam ações em um navegador, e estamos tendo problemas com algumas delas ao acessar a área de transferência para leitura ou gravação. Eles mostram um "Não é possível abrir a área de transferência".

Portanto, existe outro aplicativo que armazena a área de transferência.

Como podemos depurar isso? Existe alguma ferramenta que possa monitorar isso? AFAIK ProcMon não faz o trabalho.

As máquinas são o Windows XP.

    
por Áxel Costas Pena 18.06.2014 / 18:25

1 resposta

6

A API da Área de Transferência data do Windows 3.0 (ou antes?) e foi mal projetada. Infelizmente, em vez de ter primitivos get / set, ele usa abrir / fechar, o que possibilita que os aplicativos mantenham seu acesso por muito tempo. Alguma melhoria foi trazida pelo Vista para o tratamento dos telespectadores cadeia, mas nenhuma nova API.

Com a API existente, é possível identificar o proprietário da área de transferência somente se esse proprietário também tiver pelo menos uma janela aberta. Se o proprietário não tem janelas, então está sem sorte.

No tópico Por que minha área de transferência parou de funcionar? , Jay Parzych contribuiu com o seguinte código vbs onde a função GetClipboardLocker retorna o nome do arquivo do processo que contém a área de transferência:

<DllImport("user32.dll")> _
Public Function GetOpenClipboardWindow() As IntPtr
   End Function
 <DllImport("user32.dll", SetLastError:=True)> _
   Public Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
   End Function
Public Function GetClipboardLocker() As String
       Dim hwnd As IntPtr = GetOpenClipboardWindow()
       If hwnd <> IntPtr.Zero Then
           Dim processId As Integer
           GetWindowThreadProcessId(hwnd, processId)
           Dim p As Process = Process.GetProcessById(processId)
           GetClipboardLocker = p.Modules(0).FileName
       Else
           GetClipboardLocker = String.Empty
       End If
   End Function

Uma função similar em C # pode ser encontrada no post Obter proprietários / título da área de transferência .

    
por 13.06.2016 / 10:06