A API da área de transferência é do Windows 3.0 (ou antes?) E é mal projetada. Infelizmente, em vez de ter primitivas get / set, ele usa abrir / fechar, o que possibilita que os aplicativos mantenham seu acesso por muito tempo. Algumas melhorias foram trazidas pelo Vista para o manuseio da cadeia de visualizadores, mas nenhuma nova API.
Com a API existente, é possível identificar o proprietário da área de transferência apenas se esse proprietário também tiver pelo menos uma janela aberta. Se o proprietário não tiver janelas, uma delas estará sem sorte.
No tópico Por que minha área de transferência parou de funcionar? , Jay Parzych contribuiu com o seguinte código vbs em que 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 C # semelhante pode ser encontrada na publicação
Título / Legenda dos proprietários da área de transferência .