python - 从 32 位 python 运行 64 位 powershell
问题描述
我正在Windows Server 2012 R2 standard
使用 32Bit python 的机器上运行。
我正在尝试为 64 位系统运行 powershell 脚本,以检查注册表中是否存在密钥:
$path = "Registry::HKLM\Software\<folder>"
if (!(Test-Path $path))
{
write "$path does not exist!"
}
通过 powershell 运行时,脚本可以完美运行。
当我从 python 运行它时,它找不到密钥:
from gevent.subprocess import call
call("powershell <script.ps1>, shell=True")
经过一番研究,我发现 32bit python进程正在调用 32bit 版本的powershell。
我用这个简单的脚本验证了它,它检查正在运行的进程是 32 位还是 64 位:
powershell [System.Environment]::Is64BitProcess
将返回True
64 位进程和False
32 位进程。
手动检查此命令有效:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe [System.Environment]::Is64BitProcess
返回False
,因为这是 32 位版本的 powershell(是的,由于 WOW64 文件夹而相当混乱)。
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe [System.Environment]::Is64BitProcess
退货True
。但是运行:
from gevent.subprocess import call
call("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe [System.Environment]::Is64BitProcess", shell=True)
退货False
我错过了什么?
解决方案
您缺少的是 Windows 透明地将文件系统调用从 32 位进程重定向C:\Windows\System32
到C:\Windows\SysWOW64
:)
对此有一个简单的解决方案 - 如果 32 位进程尝试从中获取文件系统资源C:\Windows\sysnative
,Windows 将不会重定向到SysWOW64
.
从 PowerShell 很容易确定您的进程是否会受到所有这些 SysWOW64 重定向的影响,基本上:
$IsSysWOW64Process = [Environment]::Is64BitOperatingSystem -and -not [Environment]::Is64BitProcess
然而,在 python 中,我无法找到一种万无一失的方法,所以我怀疑你最好的选择是通过kernel32!IsWow64Process2()
调用ctypes
:
from ctypes import windll,c_ushort,byref
import platform
def is_syswow64_process():
if platform.architecture()[0] != '64bit':
# 32-bit OS, no syswow64 handling
return False
# Ok, 64-bit OS, let's see if the process is 32-bit
# Obtain process handle to self
this_process = windll.kernel32.GetCurrentProcess()
# Declare ref arguments
proc_type, platform_type = c_ushort(), c_ushort()
# Query Windows for the information
wow64_call = windll.kernel32.IsWow64Process2(this_process, byref(proc_type), byref(platform_type))
if wow64_call == 0:
# you'd probably want to call kernel32!GetLastError here
raise Exception("Problem querying kernel32!IsWow64Process2")
return proc_type.value == 0
现在您可以在需要时有条件地替换路径:
powershell = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
if is_syswow64_process():
powershell = re.sub("(?i)syswow64|system32", "sysnative", powershell)
call("%s .\path\to\script.ps1" % powershell)
推荐阅读
- wordpress - wordpress 和 getUserMedia 之间有问题吗?
- spring - 使用 JWT 通过标头模拟 spring 安全角色
- macos - 我的 emacs 客户端在切换应用程序时自动终止 [OSX iTerm2]
- python - 熊猫从列表列中获取唯一值
- php - 如何在 Elasticsearch 6.x 中按动态或未知字段进行聚合
- javascript - req.body 在帖子中返回空
- javascript - .ForEach (Javascript) 和回调
- java - 如何在所有测试类开始之前执行一段代码?
- sql - 更快的方法比较 SQL 子查询之间的变化?
- openshift - 在 Openshift Container 平台对象架构定义中,attributeRestrictions 是什么意思?