python - 为什么 powershell 和 python 对同一命令给出不同的结果?

标签 python powershell

为什么用Python写这个脚本

import subprocess, io
p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } |    Format-List Id,Name,Path"], stdout=subprocess.PIPE)
for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
    line = " ".join(line.split())
    print(line)

并在 Powershell 中编写命令

Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path

有不同的结果? 例如,这是 Powershell 的一些结果:

Id   : 7692
Name : NVIDIA Share
Path : C:\Program Files\NVIDIA Corporation\NVIDIA GeForce Experience\NVIDIA Share.exe

Id   : 7232
Name : Origin
Path : C:\Program Files (x86)\Origin\Origin.exe

这与 Python 相同:

Id   : 7692
Name : NVIDIA Share
Path :

Id   : 7232
Name : Origin
Path : C:\Program Files (x86)\Origin\Origin.exe

有时,当在 Powershell 中时,Python 结果中缺少路径。为什么会这样,有什么方法可以解决这个问题吗?

最佳答案

我想,喜欢 @Viet Hoang ,这是一个简单的高程问题(因为这通常是 90% 的问题)。因此,出于系统管理员的盲目信心,我决定对其进行测试。让我们以管理员身份启动 PowerShell,然后运行:

PS C:\> (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
True

好的。好的。我们有一个真正提升的 PowerShell session 。让我们启动 Python,并一劳永逸地证明@Lolman 不知道他在做什么,并证明 Python 不知道如何启动适当的提升的 PowerShell session :

PS C:\> python
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...
True

太棒了!它按预期返回...嗯...呃-哦... True .........嗯...嗯...疯了。有那个想法。 @Lolman 实际上确实知道如何尝试。

好的。现在,这需要一些创造性思维。让我们比较一下我得到的一些条目:

PowerShell

PS C:\> Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path

...

Id   : 2660
Name : powershell
Path : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Id : 31200
Name : Code
Path : C:\Users\HAL9256\AppData\Local\Programs\Microsoft VS Code\Code.exe

Id : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...

python

PS C:\> python
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...

Id   : 2660
Name : powershell
Path : 

Id   : 31200
Name : Code
Path :

Id   : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...

那么,让我们看看显示路径信息的进程和不显示路径信息的进程之间的区别。我看到很多 Program Files (x86) 但不是 Program Files...嗯...这看起来像是 32 位与 64 位的问题。

为了证明这一点,我以管理员身份启动了 32 位 Windows PowerShell (x86),并运行了相同的命令:

Windows PowerShell (x86)

PS C:\> (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
True

PS C:\> Get-Process | Where-Object { $_.MainWindowTitle } | Format-List Id,Name,Path

...

Id   : 2660
Name : powershell
Path : 

Id   : 31200
Name : Code
Path :

Id   : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...

啊哈!它确实看起来像是 32 位与 64 位的问题。好的。那么,让我们证明这一点。让我们下载 Python 64 位并再次尝试:

PS C:\> C:\Users\HAL9256\AppData\Local\Programs\Python\Python38\python.exe
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, io
>>> p = subprocess.Popen(["powershell.exe", "Get-Process | Where-Object { $_.MainWindowTitle } |    Format-List Id,Name,Path"], stdout=subprocess.PIPE)
>>> for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
...     line = " ".join(line.split())
...     print(line)
...

Id   : 2660
Name : powershell
Path : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Id : 31200
Name : Code
Path : C:\Users\HAL9256\AppData\Local\Programs\Microsoft VS Code\Code.exe

Id : 22804
Name : devenv
Path : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe

...

是的!我们现在得到了所有的信息。 PowerShell 控制台以 64 位运行,因此可以看到完整的路径和进程信息。 Python 默认是 32 位的,因此看不到 64 位进程的完整路径和进程信息。只有通过显式运行 64 位版本的 Python(从提升的 session ),我们才能看到所有路径和进程信息。

关于python - 为什么 powershell 和 python 对同一命令给出不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58984488/

相关文章:

python - 每行 Bin 元素 - NumPy 的矢量化 2D Bincount

powershell - Azure 自动化 - 每天自动重新启动一次 Web 应用程序的 Runbook

unix - powershell中等效的unix test -f命令是什么?

regex - Powershell正则表达式

sql-server - SQL Powershell错误: Invoke-Sqlcmd : The term 'Invoke-Sqlcmd' is not recognized as the name of a cmdlet

powershell - 重命名文件以符合标准

python - 如果它包含 pandas 数据框中的子字符串,则替换整个字符串

Python - 将格式化行导入为索引列表对象

python - 使用嵌入式 python 和 SimpleTemplate Engine 作为字符串传递给 template()

python - 如何创建用于识别 CR 的层规则?