При скачивании файла с интернета он маркируется для защиты таким образом:
Как с помощью своего приложения отслеживать файлы с такой пометкой защиты?
Например при перетаскивании файла на приложение.
Ответ
Скорее всего, вам нужно просто разблокировать файл в случае, если он заблокирован.
Официальный путь — вызовите 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);
Комментариев нет:
Отправить комментарий