When downloading a file from the Internet, it is marked for protection as follows:

enter image description here

How can I track files with this security mark using my application?
For example, when dragging a file to an application.

    1 answer 1

    Most likely, you just need to unlock the file in case it is locked.

    The official way is to call the Unblock-File Powershell-cmdlet. To do this, install the System.Management.Automation nuget package, and use the following code:

     using (var ps = PowerShell.Create()) { ps.AddCommand("Unblock-File", true); ps.AddParameter("LiteralPath", fullPath); ps.Invoke(); } 

    Alternative way - you can take advantage of the knowledge that in current versions of Windows, data about the locked file is contained in an alternative NTFS data stream called Zone.Identifier, and remove it via P / Invoke (the code is lent to en.SO ):

     [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool DeleteFile(string name ); public bool Unblock(string fileName) { return DeleteFile(fileName + ":Zone.Identifier"); } 

    Okay, if you really only need to check if there is protection, you will have to work with COM objects. The COM object PersistentZoneIdentifier is responsible for blocking. The code is borrowed here and here , and adapted.

     using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; static class BlockChecker { public static bool IsBlocked(string path) { object persistZoneId = Activator.CreateInstance( Type.GetTypeFromCLSID(Guid.Parse(CLSID_PersistentZoneIdentifier))); var zoneIdentifier = (IZoneIdentifier)persistZoneId; var persistFile = (IPersistFile)persistZoneId; try { persistFile.Load(path, 0); // STGM_READ var id = zoneIdentifier.GetId(); return id == URLZONE.URLZONE_INTERNET || id == URLZONE.URLZONE_UNTRUSTED; } catch { return false; } finally { if (persistZoneId != null) Marshal.FinalReleaseComObject(persistZoneId); } } const string CLSID_PersistentZoneIdentifier = "0968e258-16c7-4dba-aa86-462dd61e31a3"; const string IID_IZoneIdentifier = "cd45f185-1b21-48e2-967b-ead743a8914e"; [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid(IID_IZoneIdentifier)] public interface IZoneIdentifier { URLZONE GetId(); void SetId(URLZONE zone); void Remove(); } public enum URLZONE : uint { URLZONE_LOCAL_MACHINE = 0, URLZONE_INTRANET = 1, URLZONE_TRUSTED = 2, URLZONE_INTERNET = 3, URLZONE_UNTRUSTED = 4, } } 

    Use the obvious way: BlockChecker.IsBlocked(fullPath) .

    If the file does not exist, then true will be returned, so check it yourself.

    If anything, you can remove the lock with

     zoneIdentifier.Remove(); persistFile.Save(path, true); 
    • one
      The author, it seems, asks not to remove the block, but to check its availability - Andrey NOP
    • one
      @AndreyNOP: Hmm. And true. Let me see how easy it is to check it out. - VladD
    • You just need to know whether the file is protected by the system, there is no need to remove the protection. This is to ensure that the rest of the files without protection (installed programs, etc.) are not launched through the application. - Vitokhv
    • one
      @VladD, check for the existence of fileName + ":Zone.Identifier" ? - Andrey NOP
    • Tell me, how can I bind the code to the condition? For example, if there is protection on a file, then display the message: MessageBox.Show("Файл защищен"); - Vitokhv