繁体   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