0

我是 PInvoke 呼叫的新手。我用谷歌搜索了这个,因为这似乎是一个很简单的问题,但并不快乐。

我正在连续进行多次 Windows Mobile API 调用(以检测我的应用程序是否已经在运行,然后重新激活它)。一切正常,花花公子,但我想在它不能正常工作的时候加入日志记录等。

在编写此代码时,我发现即使我的调用显然返回了有效结果并且后续调用成功使用了有效结果(我认为证明它是有效的),我也会收到错误代码。

例如,我调用 CreateToolhelp32Snapshot,它为我提供了当前运行进程快照的句柄。在返回错误 6 后立即调用 Marshal.GetLatWin32Error,这显然意味着无效的句柄。但是返回值被后续调用其他方法成功使用,整个过程正常。绝对是这个特定的调用设置了错误 6,因为如果您在调用之前调用 Marshal.GetLatWin32Error,它会返回 0。

对 Process32First 和 Process32Next 的调用表现出类似的行为,即它们很高兴地给我进程信息,但有时会设置错误 6。我(认为)我知道这是因为我在每次调用之前和之后立即调用 Marshal.GetLatWin32Error,有时它在之前和 6 之前是 0后。目前我总是得到一个成功的结果(或者一个处理后续调用的句柄,或者一个转换为 1 如果 int 或 true 如果 bool 和进程信息成功复制到我的缓冲区中的值)。

所以……我应该关心吗?这一切都在工作....如果我返回一个被其余过程成功使用的结果,我是否关心设置了什么错误?我的直觉说是的,我当然愿意?无论哪种方式,如果我显然得到了成功的结果但也设置了错误代码,我怎么知道一切是否正常?我做噩梦发布一个不稳定的系统,它不会给我有用的错误信息............

更新

这是我的 loggong 代码的结果,试图为任何感兴趣的人说明我在说什么。简而言之,代码检查自身是否已经运行,然后检查客户端是否已经运行,如果找到则重新激活客户端。

Method name: CreateToolhelp32Snapshot, Result: 605618176, Pre-call error code: 0, Post-call error code: 6
Method name: Process32First, Result: True, Pre-call error code: 6, Post-call error code: 6               
Method name: Process32Next, Result: True, Pre-call error code: 6, Post-call error code: 6                
Method name: Process32Next, Result: True, Pre-call error code: 6, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                                                                            
Method name: Process32Next, Result: False, Pre-call error code: 0, Post-call error code: 18              
Method name: CloseToolhelp32Snapshot, Result: True, Pre-call error code: 18, Post-call error code: 6     
Method name: CreateToolhelp32Snapshot, Result: 605618176, Pre-call error code: 6, Post-call error code: 0
Method name: Process32First, Result: True, Pre-call error code: 0, Post-call error code: 0               
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                
Method name: Process32Next, Result: True, Pre-call error code: 0, Post-call error code: 0                                                                      
Method name: Process32Next, Result: False, Pre-call error code: 0, Post-call error code: 18              
Method name: CloseToolhelp32Snapshot, Result: True, Pre-call error code: 18, Post-call error code: 0     
Method name: ShowWindow, Result: True, Pre-call error code: 0, Post-call error code: 120                 
Method name: SetForegroundWindow, Result: True, Pre-call error code: 120, Post-call error code: 6        

结果始终为真,除了对 Process32Next 的最后一次调用,其中代码 18 的失败表示已到达最后一个条目。而且我刚刚注意到 ShowWindow 导致了不支持的错误 120,所以我会取消这个调用。

所以我的两个实际问题是:

为什么我成功时出现错误?
而且,当调用前和调用后错误相同时,我如何知道这是旧错误还是同一错误的第二次出现?

4

2 回答 2

2

除非 CreateToolhelp32Snapshot 返回 INVALID_HANDLE_VALUE,否则不应调用 GetLastWin32Error (GetLastError)。

http://msdn.microsoft.com/en-us/library/ms682489(VS.85).aspx

于 2009-03-03T13:36:20.113 回答
1

您希望 GetLastError() 在每次成功调用任何函数后返回 0。但这意味着这些函数在其结语中调用 SetLastError(0) 并不总是这样做。这就是为什么您无法区分旧错误代码和新错误代码的原因。仅在 MSDN 告诉您这样做的情况下调用 GetLastError()。

于 2009-03-03T13:41:30.800 回答