In this question I have searched for a simple solution to unblock files.
Thanks to all the comments and answer, I have found a simple solution by PInvoking DeleteFile
.
It works, but because I've never used file-operations through PInvoke (Win32), I don't know if there are some pitfalls or if there is another method of calling DeleteFile
to delete the alternate stream of a file.
What I also don't know is if I have to wrap the call in a try/catch or if it is enough just to look the at the boolean result. In my tests, no exceptions were raised, but I don't know what will happen in the real world.
public class FileUnblocker {
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteFile(string name );
public bool Unblock(string fileName) {
return DeleteFile(fileName+ ":Zone.Identifier");
}
}
Does this code look reliable?
Update
I had posted an incomplete method (the unblock method didn't concatenate the "Zone.Identifier" literal to the file name). I have corrected this now, sorry.
Calling the native method will never raise an exception. If the file deletion fails, for whatever reason, the call to
DeleteFile
returns false.Your P/Invoke code is good. You are correctly using Unicode characters, setting
SetLastError
totrue
and the parameter marshalling is correct. To check for errors look for the value of the boolean return fromDeleteFile
. If it is false (i.e. the call failed) then callMarshal.GetLastWin32Error
to find out the Win32 error code.The most obvious causes for the function to fail are:
For 1 and 2 an error code of
ERROR_FILE_NOT_FOUND
will be returned. For 3 you will be given an error code ofERROR_ACCESS_DENIED
.I made a small refinement to the code. You can now just pass your startup path to the UnblockPath() function and it will automatically unblock all of the files and sub directory files for your executable. It could be refined further to only search for .exe, .dll, etc.