Windows Mobile API calls - success but GetLastWin32Error returns error code - should I be worried?

StackOverflow https://stackoverflow.com/questions/606048

Question

I am a newbie to PInvoke calls. I have googled this as it seems like a simple enough question but no joy.

I am making muliple Windows Mobile API calls in a row (to detect if my app is already running and then re-activate it). Everything works fine and dandy but I wanted to put in logging etc for the times when it doesn't work OK.

While writing this code I found that I will get error codes even when my calls apparently return a valid result and the valid result is used successfully by a subsequent call (proving it's valid I think.)

E.g. I call CreateToolhelp32Snapshot which gives me back a handle to a snapshot of currently running processes. Calling Marshal.GetLatWin32Error immediatley after returns Error 6 which apparently means Invalid Handle. But the returned value is used successfully by the subsequent calls to other methods and the whole process works. It's definitely this particular call that sets Error 6 because if you call Marshal.GetLatWin32Error just before the call it returns 0.

Calls to Process32First and Process32Next exhibit similar behaviour i.e. they give me process information happily but sometimes set Error 6. I (think) I know this is happening because I call Marshal.GetLatWin32Error immediatley before and after each call and sometimes it is 0 before and 6 after. Currently I am always getting a successful result (either a handle that works with subsequent calls or a value that casts to 1 if int or true if bool and process info successfully copied into my buffer).

So.....should I care? It's all working.... Do I care what error gets set if I get back a result that is used successfully by the rest of the process? My gut says yes I do, surely? Either way, how do I actually know if everything is OK if I apparently get a successful result back but an error code is also set? I am having nightmares about releasing an unstable system that won't be giving me useful error information back........

UPDATE

This is the results of my loggong code to try and illustrate what I'm talking about for anyone interested. In brief, the code checks for already-running copies of itself, then for already-running copies of the client and then reactivates client if it was found.

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        

The results are always true except for the last calls to Process32Next for which failure with code 18 indicates the last entry was reached. And I've just noticed ShowWindow is resulting in Error 120 which is not supported so I'll take that call out.

So my two actual questions are:

Why the errors when I got a success?
And, when the pre-call and post-call errors are the same, how do I know if this was the old error or a second occurence of the same error?

Was it helpful?

Solution

You shouldn't be calling GetLastWin32Error (GetLastError) unless CreateToolhelp32Snapshot returns INVALID_HANDLE_VALUE.

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

OTHER TIPS

You expect GetLastError() to return 0 after each successful call of any function. But this implies that those functions call SetLastError(0) in their epilogue which is not always done. That's why you can't distinguish between an old error code and a new one. Only call GetLastError() for cases MSDN tells you to do so.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top