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 .