簡體   English   中英

從 python 腳本中取消阻止 windows 中的文件

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM