<p>在命令行上传递密码存在很大的安全风险。通过管理权限,可以检索该信息(startup info对象)并提取密码。更好的解决方案是将7zip作为一个进程打开,并将密码输入到其标准输入中。在</p>
<p>下面是一个命令行压缩“源.txt“进入”dest.7z“:</p>
<pre><code>CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"
</code></pre>
<p>首先需要将密码转换为输入字符串。请注意,7-zip要求在终端中输入密码。您可以使用特殊字符,只要它们可以在终端中表示。终端的编码很重要!例如,在匈牙利语窗口中,您可能希望使用“cp1250”编码。在所有情况下,标准输入都是二进制文件,它需要一个二进制字符串(python3中的“bytes”)。如果您希望安全起见,您可以将密码限制为纯ascii,并按如下方式创建输入:</p>
^{pr2}$
<p>如果您知道终端的编码,那么您可以将密码转换为该编码。您还可以检测密码是否不能与系统编码一起使用。(顺便说一句,这也意味着它也不能交互使用。)</p>
<p>(上次检查时,Windows上的不同区域设置的终端编码是不同的。也许有个窍门可以把它改成UTF-8,但我不知道怎么改。)</p>
<p>以下是执行命令的方式:</p>
<pre><code>import subprocess
import typing
def execute(cmd : typing.List[str], input: typing.Optional[bytes] = None, verbose=False, debug=False, normal_priority=False):
if verbose:
print(cmd)
creationflags = subprocess.CREATE_NO_WINDOW
if normal_priority:
creationflags |= subprocess.NORMAL_PRIORITY_CLASS
else:
creationflags |= subprocess.BELOW_NORMAL_PRIORITY_CLASS
if debug:
process = subprocess.Popen(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=subprocess.PIPE,
creationflags=creationflags)
else:
process = subprocess.Popen(cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
stdin=subprocess.PIPE, creationflags=creationflags)
if input:
process.stdin.write(input)
process.stdin.flush()
returncode = process.wait()
if returncode:
raise OSError(returncode)
CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"
input = (PASSWORD + "\r\n").encode("ascii")
execute(CMD, input)
</code></pre>
<p>这也展示了如何降低进程优先级(在压缩大量数据时,这通常是一个好主意),还展示了如何将标准输出和标准错误转发到控制台。在</p>
<p>绝对正确的解决方案是加载7-zip DLL并使用其API。(我没有检查,但可能会使用8位二进制字符串作为密码。)</p>
<p>注意:本例适用于Python3,但Python2也同样适用。在</p>