Як перевірити, яку програму має вміст буфера обміну?


9

Ми розгортаємо деякі віртуальні машини з програмним забезпеченням роботів, яке виконує дії в браузері, і ми маємо проблеми з деякими з них під час доступу до буфера обміну для читання чи запису. Вони показують "Неможливо відкрити буфер обміну".

Таким чином, є будь-яка інша програма, яка містить буфер обміну

Як ми можемо це налагодити? Чи є якийсь інструмент, який може контролювати це? AFAIK ProcMon не робить цю роботу.

Машини - це Windows XP.


Це відбувається в мінімальній конфігурації завантаження?
Рамхаунд

Програмне забезпечення роботів не працює в безпечному режимі, це одна з труднощів
Аксель Костас Пена

1
Я не говорив про безпечний режим. Я сказав, що в мінімальній конфігурації завантаження є різниця.
Рамхаунд

Буфер обміну вручну: збережіть текст у файл, зателефонуйте в цей файл, видаліть файл.
Wutnaut

У машині @Ramhound багато компонентів, багато з яких необхідні для роботи робота. Починаючи з чистої машини і встановлюючи програмне забезпечення по черзі до відтворення помилки буде дуже дорого.
Аксель Костас Пена

Відповіді:


9

API буфера обміну датується з Windows 3.0 (або раніше?) І погано розроблений. На жаль, замість того, щоб отримати / встановити примітиви, він використовує відкритий / закритий, що дозволяє програмам занадто довго утримувати його доступ. Певне поліпшення принесло Vista для управління мережею глядачів, але нового API.

Із наявним API можна ідентифікувати власника буфера обміну, лише якщо цей власник також має принаймні одне відкрите вікно. Якщо у власника немає вікон, то одного не пощастило.

У темі Чому мій буфер обміну перестав працювати? , Jay Parzych вніс наступний код vbs, де функція GetClipboardLocker повертає ім'я файлу процесу, що містить буфер обміну:

<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

Аналогічну функцію C # можна знайти у публікації Отримати власників буфера обміну Назва / Підпис .


Оскільки в нашому сценарії ми можемо запевнити, що будь-який процес, який виконує, не має вікна, я позначу це правильною відповіддю. Дякую.
Аксель Костас Пена
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.