[英]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.