Question

I used to get correct Win32Exception but now it is strange

Win32Exception ex1 = new Win32Exception();   
MoveFileWithProgress(oldFile, newFile, new CopyProgressRoutine(this.CopyProgressHandler), IntPtr.Zero, MoveFileFlags.MOVE_FILE_REPLACE_EXISTSING | MoveFileFlags.MOVE_FILE_WRITE_THROUGH | MoveFileFlags.MOVE_FILE_COPY_ALLOWED);
Win32Exception ex2 = new Win32Exception();    

Getting

ex1: The system cannot find the file specified

ex2: the system could not find the environment option that was entered

even though file is there and operation is successful.


Additional information:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool MoveFileWithProgress(string lpExistingFileName,
       string lpNewFileName, CopyProgressRoutine lpProgressRoutine,
       IntPtr lpData, MoveFileFlags dwFlags);
Was it helpful?

Solution

You need to check the return value of the call to MoveFileWithProgress. Only if it returns false did the function fail.

You must only call Marshal.GetLastWin32Error or create a new Win32Exception if the function failed. Like this:

if (!MoveFileWithProgress(...))
    throw new Win32Exception();

If you ask for the last error after a function call that succeeded you can get an error code that applies to an earlier function call that did fail. Basically, the last error code is ill-defined in the case where the API call succeeds. The documentation takes great care only to tell you to call GetLastError in case of failure.

This same principle applies to most Win32 functions but there are sometimes exceptions to this standard pattern. For instance, the registry functions return Win32 error codes directly. Always read the documentation carefully.

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