После вызова COM API получение исключений EOSError (доступ запрещен), но только при переключении пользователей или блокировке станции в Windows 7
У меня есть приложение Delphi 6, которое получает исключение EOSError, код 5, доступ запрещен, но только когда я переключаюсь на другую учетную запись пользователя Windows 7 или блокирую станцию. Я распечатываю трассировку стека, но, похоже, ошибка идет прямо из оператора Application.Run() с Application.ProcessMessages(), расположенного непосредственно под ним в стеке. Остальная часть стека - мой код обработки исключений.
Во время работы код выполняет вызовы ShellExecuteEx() и обращается к объекту COM/ActiveX, но только когда пользователь явно нажимает кнопку. Это происходит только в Windows 7, а не в Windows XP. Я изменил свое приложение так, чтобы оно полностью устанавливалось в каталог данных приложения пользователя и поэтому не требовало доступа к каким-либо каталогам прав администратора. Я знаю, что это не имеет значения, но я указываю это на всякий случай.
Когда это происходит, исключения приходят быстро и яростно. Я перехватываю их и выкидываю в журнал ошибок, чтобы не задевать пользователя множеством диалоговых окон. Может кто-нибудь сказать мне, что может вызвать поток этих ошибок, просто отключившись или заблокировав в настоящее время вошедшего в систему пользователя? Почему у моего приложения возникают проблемы, если текущая учетная запись пользователя не активна?
Одна мысль. Не вызывают ли некоторые растровые операции проблемы, если пользователь в данный момент не вошел в систему? У меня есть вращающееся облако тегов, которое непрерывно выполняет растровые операции Windows API для обновления изображения облака тегов. Может ли это иметь какое-то отношение к этому?
Если это так, я мог бы попытаться деактивировать облако тегов, когда текущий пользователь выключен или заблокирован, но я считаю, что мне понадобится код для Delphi, который реагирует на события, упомянутые в этом посте переполнения стека:
Как определить команду "Блокировать этот компьютер" из приложения WPF?
ОБНОВЛЕНИЕ: я сделал дополнительное тестирование. Ошибки не возникают, пока я не получаю доступ к интерфейсу COM/ActiveX для Evernote, программного обеспечения, с которым я взаимодействую. Как только я сделаю первый вызов Evernote vai COM API, ошибки происходят сразу же, когда я блокирую станцию.
2 ответа
Я нашел проблему. Это потому, что я вызываю Controls.TMouse.GetCursorPos() по таймеру, чтобы обновить вид облака тегов, о котором я упоминал в своем первоначальном посте. Эта функция вызывает исключение, если текущий рабочий стол недоступен, например, когда вы переключаетесь на другую учетную запись пользователя или блокируете станцию. Этот пост переполнения стека охватывает проблему из общего контекста WinAPI для функции GetCursorPos ().
Вызов TMouse.GetCursorPos иногда завершается с ошибкой "Сбой вызова функции ОС"
В отличие от автора вышеупомянутого поста, это происходит только со мной в Windows 7, а не в Windows XP. Мне нужно изменить свой код, чтобы он определял, когда активный рабочий стол больше не доступен, и подавлял этот вызов, используя методы обнаружения блокировки / разблокировки / входа / выхода из сеанса, описанные в сообщении, приведенном ниже, как это было предложено мне TLama. Смотрите ответ Дэвида Хеффернана:
Что приложение должно сделать для того, чтобы "поддерживать" службы удаленных рабочих столов?
Если возможно, ваши пользователи могут перевести вашу программу в режим совместимости XP SP3, что может устранить эти ошибки. Это явно обходной путь.
Ты можешь использовать processmonitor
вместе с filemon
чтобы увидеть, что происходит в Windows: http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
для полного комплекта: http://technet.microsoft.com/en-us/sysinternals/bb842062