<p><strong>免责声明:</strong>我是下面提到的修复程序的作者。</p>
<p>要在带有Python2.7的windows上支持unicode命令行,可以使用
<a href="https://gist.github.com/vaab/2ad7051fc193167f15f85ef573e54eb9" rel="nofollow noreferrer">this patch</a>到<code>subprocess.Popen(..)</code></p>
<p><strong>情况</strong></p>
<p>Python 2在windows上对unicode命令行的支持非常差。</p>
<p>被严重窃听:</p>
<ul>
<li><p>从调用方向系统发出unicode命令行(通过<code>subprocess.Popen(..)</code>),</p></li>
<li><p>从被叫方读取当前的命令行unicode参数(通过<code>sys.argv</code>),</p></li>
</ul>
<p>它在Python 2上被确认并<a href="http://bugs.python.org/issue19264" rel="nofollow noreferrer">won't be fixed</a>。这些在Python 3中是固定的。</p>
<p><strong>技术原因</strong></p>
<p>在Python 2中,<code>subprocess.Popen(..)</code>和<code>sys.argv</code>的windows实现使用非unicode就绪的windows系统调用<code>CreateProcess(..)</code>(请参见Python<a href="https://github.com/python/cpython/blob/2.7/PC/_subprocess.c#L464" rel="nofollow noreferrer">code</a>,和MSDN<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx" rel="nofollow noreferrer">doc of CreateProcess</a>),而不使用<code>GetCommandLineW(..)</code>来获取<code>sys.argv</code>。</p>
<p>在Python 3中,<code>subprocess.Popen(..)</code>的windows实现使用正确的windows系统调用<code>CreateProcessW(..)</code>从<code>3.0</code>开始(请参见<code>3.0</code>中的^{<a5}),使用<code>GetCommandLineW(..)</code>从<code>3.3</code>开始(请参见<code>3.3</code>中的^{<a6})。</p>
<p><strong>如何修复</strong></p>
<p>给定的<a href="https://gist.github.com/vaab/2ad7051fc193167f15f85ef573e54eb9" rel="nofollow noreferrer">patch</a>将利用<code>ctypes</code>模块调用C窗口
直接系统<code>CreateProcessW(..)</code>。它通过重写私有方法<code>Popen._execute_child(..)</code>和私有函数<code>_subprocess.CreateProcess(..)</code>从windows系统库中设置和使用<code>CreateProcessW(..)</code>,提出了一个新的固定<code>Popen</code>对象,以尽可能模拟在Python中的工作方式<code>3.6</code>。</p>
<p><strong>如何使用它</strong></p>
<p>如何使用给定的修补程序将通过<a href="http://vaab.blog.kal.fr/2017/03/16/fixing-windows-python-2-7-unicode-issue-with-subprocesss-popen/" rel="nofollow noreferrer">blog post explanation</a>演示。它还显示了如何读取当前进程
<code>sys.argv</code>与<a href="http://code.activestate.com/recipes/572200/" rel="nofollow noreferrer">another fix</a>一起。</p>