[英]Unblock a file in windows from a python script
我可以在 Windows(7) 中取消阻止 windows(从 Internet 下载)从 python 脚本自动阻止的文件吗? 遇到此类文件时会引发 WindowsError。 我想捕捉这个异常,并运行一个 powershell 脚本,类似于:
Parameter Set: ByPath
Unblock-File [-Path] <String[]> [-Confirm] [-WhatIf] [ <CommonParameters>]
Parameter Set: ByLiteralPath
Unblock-File -LiteralPath <String[]> [-Confirm] [-WhatIf] [ <CommonParameters>]
我不知道 powershell 脚本。 但如果我有一个,我可以从 python 调用它。 你们能帮忙吗?
是的,您所要做的就是从Python调用以下命令行:
powershell.exe -Command Unblock-File -Path "c:\path\to\blocked file.ps1"
聚会迟到了。 . . . 我发现块状态只是附加在 NTFS 中的一个额外的“文件”(流),它实际上可以通过普通方式访问和操作。 这些称为替代数据流。 用于文件阻塞(互联网区域指定)的 ADS 称为“:Zone.Identifier”,我认为其中包含一些有用的信息:
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://www.google.com/
HostUrl=https://imgs.somewhere.com/product/1969297/some-pic.jpg
我发现的所有其他信息都说只删除这个额外的流......但是,就我个人而言,我想保留这个信息......所以我尝试将ZoneId更改为 0,但它仍然在 Windows 文件中显示为已阻止特性。 我决定将它移到另一个流名称,以便以后仍然可以找到它。
下面的脚本源自一个更通用的脚本,称为 pyADS。 我只关心删除/更改 Zone.Identifier 附加流——这一切都可以用简单的 Python 命令完成。 所以这是一个精简版。 它列出了几个非常好的背景参考。 我目前正在运行最新的 Windows 10 和 Python 3.8+; 我不保证这适用于旧版本。
import os
'''
References:
Accessing alternative data-streams of files on an NTFS volume https://www.codeproject.com/Articles/2670/Accessing-alternative-data-streams-of-files-on-an
Original ADS class (pyADS) https://github.com/RobinDavid/pyADS
SysInternal streams applet https://docs.microsoft.com/en-us/sysinternals/downloads/streams
Windows: killing the Zone.Identifier NTFS alternate data stream https://wiert.me/2011/11/25/windows-killing-the-zone-identifier-ntfs-alternate-data-stream-from-a-file-to-prevent-security-warning-popup/
Zone.Information https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/6e3f7352-d11c-4d76-8c39-2516a9df36e8
About URL Security Zones https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/ms537183(v=vs.85)?redirectedfrom=MSDN
GREAT info: How Windows Determines That the File.... http://woshub.com/how-windows-determines-that-the-file-has-been-downloaded-from-the-internet/
Dixin's Blog: Understanding File Blocking and Unblocking https://weblogs.asp.net/dixin/understanding-the-internet-file-blocking-and-unblocking
'''
class ADS2():
def __init__(self, filename):
self.filename = filename
def full_filename(self, stream):
return "%s:%s" % (self.filename, stream)
def add_stream_from_file(self, filename):
if os.path.exists(filename):
with open(filename, "rb") as f: content = f.read()
return self.add_stream_from_string(filename, content)
else:
print("Could not find file: {0}".format(filename))
return False
def add_stream_from_string(self, stream_name, bytes):
fullname = self.full_filename(os.path.basename(stream_name))
if os.path.exists(fullname):
print("Stream name already exists")
return False
else:
fd = open(fullname, "wb")
fd.write(bytes)
fd.close()
return True
def delete_stream(self, stream):
try:
os.remove(self.full_filename(stream))
return True
except:
return False
def get_stream_content(self, stream):
fd = open(self.full_filename(stream), "rb")
content = fd.read()
fd.close()
return content
def UnBlockFile(file, retainInfo=True):
ads = ADS2(file)
if zi := ads.get_stream_content("Zone.Identifier"):
ads.delete_stream("Zone.Identifier")
if retainInfo: ads.add_stream_from_string("Download.Info", zi)
### Usage:
from unblock_files import UnBlockFile
UnBlockFile(r"D:\Downloads\some-pic.jpg")
前:
D:\downloads>dir /r
Volume in drive D is foo
Directory of D:\downloads
11/09/2021 10:05 AM 8 some-pic.jpg
126 some-pic.jpg:Zone.Identifier:$DATA
1 File(s) 8 bytes
D:\downloads>more <some-pic.jpg:Zone.Identifier:$DATA
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://www.google.com/
HostUrl=https://imgs.somewhere.com/product/1969297/some-pic.jpg
后:
D:\downloads>dir /r
Volume in drive D is foo
Directory of D:\downloads
11/09/2021 10:08 AM 8 some-pic.jpg
126 some-pic.jpg:Download.Info:$DATA
1 File(s) 8 bytes
从此页面了解Unblock-File
命令: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-7.2
在内部,
Unblock-File
cmdlet 删除Zone.Identifier备用数据 stream,其值为3
表示它是从 Internet 下载的。
要从文件path\to\file.ext
中删除备用数据 stream ads_name
,只需删除path\to\file.ext:ads_name
:
try:
os.remove(your_file_path + ':Zone.Identifier')
except FileNotFoundError:
# The ADS did not exist, it was already unblocked or
# was never blocked in the first place
pass
# No need to open up a PowerShell subprocess!
(同样,要检查文件是否被阻止,您可以使用os.path.isfile(your_file_path + ':Zone.Identifier')
)
在 PowerShell 脚本中,您可以为此使用Unblock-File
,或者简单地使用Remove-Item -Path $your_file_path':Zone.Identifier'
。
Remove-Item
还具有用于备用数据流的特定标志: Remove-Item -Stream Zone.Identifier
(您可以在多个文件中使用 pipe 或单个-Path
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.