问题
I have a Delphi 6 application that is getting an EOSError Exception, code 5, access denied but only when I switch away to another Windows 7 user account, or I Lock the station. I am printing out a stack trace but the error appears to be coming straight from the Application.Run() statement with Application.ProcessMessages() immediately beneath it on the stack. The rest of the stack is my Exception handling code.
During operation the code does make calls to ShellExecuteEx() and accesses a COM/ActiveX object, but only when the user explicitly clicks a button. This only happens on Windows 7, not on Windows XP. I changed my application so that it installs completely to the user app data directory and therefore does not require access to any admin rights directories. I know that shouldn't matter but I'm pointing it out just in case.
When this happens the Exceptions come fast and furious. I trap them and dump them to an Error Log to avoid plaguing the user with a sea of dialog boxes. Can anyone tell me what would trigger a flood of these errors merely by switching away from or locking the currently logged-in user? Why would my app run into trouble when the current user account is not active?
One thought. Do some bitmap operations cause trouble if the user is not currently logged in? I do have a spinning tag cloud that does Windows API bitmap operations continually to update the tag cloud image. Could that have something to do with it?
If so, I could try deactivating the tag cloud when the current user is switched away or locked, but I believe I would need code for Delphi that reacts to the events mentioned in this Stack Overflow post:
How do I detect a Lock This Computer command from a WPF application?
UPDATE: I have done some additional testing. The errors do not occur until I access the COM/ActiveX interface for Evernote, the software I am interacting with. Once I make the first call to Evernote vai the COM API, the errors happen immediately when I Lock the station.
回答1:
I found the problem. It's because I am calling Controls.TMouse.GetCursorPos() on a timer to update the tag cloud view I mentioned in my original post. That function will raise an Exception if the current desktop is unavailable, like when you switch to another user account or Lock the station. This Stack Overflow post covers the issue from a general WinAPI context for the GetCursorPos() function.
Call to TMouse.GetCursorPos sometimes fails with "A call to an OS function failed"
In contrast to the author of the above post, it only happens to me on Windows 7 and not on Windows XP. I need to change my code to detect when the active desktop is no longer available and suppress that call using the session lock/unlock/logon/logoff detection techniques covered in the post linked below as suggested to me by TLama. See DavidHeffernan's answer:
What does an application have to do in order "support" Remote Desktop Services?
回答2:
If possible for your users to change your program to compatibility mode XP SP3 that may eliminate those errors. This is obviously a workaround.
You can use processmonitor
along with filemon
in order to see what is going on on windows:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
for the full suite: http://technet.microsoft.com/en-us/sysinternals/bb842062
来源:https://stackoverflow.com/questions/12773935/after-com-api-call-getting-eoserror-exceptions-access-denied-but-only-when-sw