Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

Как проверить у файла наличие защиты?

При скачивании файла с интернета он маркируется для защиты таким образом:

Как с помощью своего приложения отслеживать файлы с такой пометкой защиты? Например при перетаскивании файла на приложение.


Ответ

Скорее всего, вам нужно просто разблокировать файл в случае, если он заблокирован.
Официальный путь — вызовите Powershell-cmdlet Unblock-File. Для этого установите nuget-пакет System.Management.Automation, и воспользуйтесь таким кодом:
using (var ps = PowerShell.Create()) { ps.AddCommand("Unblock-File", true); ps.AddParameter("LiteralPath", fullPath); ps.Invoke(); }

Альтернативный путь — можно воспользоваться знанием о том, что в текущих версиях Windows данные о заблокированном файле содержатся в альтернативном потоке данных NTFS под названием Zone.Identifier, и убрать его через P/Invoke (код одолжен на 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"); }

Окей, если вам и правда нужно лишь проверить, есть ли защита, придётся поработать с COM-объектами. За блокировку отвечает COM-объект PersistentZoneIdentifier. Код одолжен здесь и здесь, и адаптирован.
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, } }
Пользоваться очевидным образом: BlockChecker.IsBlocked(fullPath)
Если файла не существует, то будет возвращено true, так что проверяйте самостоятельно.
Если что, вы можете и удалить блокировку при помощи
zoneIdentifier.Remove(); persistFile.Save(path, true);

Комментариев нет:

Отправить комментарий