[英]Powershell: Determine if a process is 32 or 64 bit
有沒有辦法確定給定的進程ID是針對32位還是64位進程? 我正在使用Powershell v3.0
試試這個:
Add-Type -MemberDefinition @'
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process(
[In] System.IntPtr hProcess,
[Out, MarshalAs(UnmanagedType.Bool)] out bool wow64Process);
'@ -Name NativeMethods -Namespace Kernel32
Get-Process -Id $id | Foreach {
$is32Bit=[int]0
if ([Kernel32.NativeMethods]::IsWow64Process($_.Handle, [ref]$is32Bit)) {
"$($_.Name) $($_.Id) is $(if ($is32Bit) {'32-bit'} else {'64-bit'})"
}
else {"IsWow64Process call failed"}
}
這里應該檢查以確保操作系統是64位,否則所有進程都是32位。
編者注 :雖然這篇文章沒有回答這個問題 - 這是為了確定給定的進程是否為32位 - 但它提供了一個方便的提示,用於確定當前進程是否為。
試試這個,這是我所知道的最簡單的方法。 在64位應用程序中,指針長度為8個字節。 在32位應用程序中,指針長度為4位。
If([IntPtr]::Size -eq 4)
{
Write-Host "32 bit"
}
Else
{
Write-Host "64 bit"
}
下面是用於在源代碼Get-32BitProcess
功能 ,周圍的包裝Get-Process
僅報告32位的進程。
注意事項:
僅支持本地進程,因此不支持-ComputerName
參數。 參數-Module
和-FileVersionInfo
也不受支持,但您可以使用這些參數管道到Get-Process
調用。
測試由不同用戶創建的進程的位數需要提升 (以管理員身份運行),因此要檢查所有 32位進程,請使用提升運行。
如果您在沒有提升的情況下運行,則會警告您只能鎖定當前用戶的進程; 使用-WarningAction SilentlyContinue
使警告靜音。
由於32位和64位進程之間的區別僅在64位版本的Windows上有意義,因此該函數拒絕在32位版本上運行 - 只需在那里使用Get-Process
。
要使用它來解決OP的問題,請使用當前進程的示例( $PID
):
$is32Bit = [bool] (Get-32BitProcess -ID $PID)
也就是說,給定有效的PID(進程ID), Get-32BitProcess
輸出表示進程的[System.Diagnostics.Process]
對象, 如果目標進程是32位, 則報告為Get-Process
; 如果是64位進程, 則不輸出任何內容。
簡單地列出所有正在運行的32位進程(具有高程:系統范圍;沒有高程:由當前用戶創建):
Get-32BitProcess
Get-32BitProcess
源代碼 :
function Get-32BitProcess {
<#
.SYNOPSIS
Gets 32-bit processes running on the local 64-bit Windows computer.
.DESCRIPTION
By default, all accessible 32-bit processes are returned:
- Without elevation, you're limited to querying processes created in the context
of the current user, and a warning to that effect is displayed.
- With elevation, all system-wide 32-bit processes are output; inaccessible
system process (which are inherently 64-bit) are ignored.
To see which ones are ignored, pass -Verbose.
This function is in effect a filtering wrapper around Get-Process that only
operates on 32-bit processes.
Parameters are the same as for Get-Process, with the following exceptions:
* only *local* 32-bit processes can be retrieved, so the -ComputerName parameter
is not supported.
* parameters -FileVersionInfo and -Module are not supported; however, you
can simply pipe this function's output to a Get-Process call with these
parameters.
Note that you'll only get output for a given process if it is indeed a 32-bit
process; when in doubt, pass -Verbose.
.NOTES
Inspired by https://stackoverflow.com/a/23025963/45375
Refuses to run on 32-bit editions of Windows, because the distinction between
32-bit and 64-bit is only meaningful in 64-bit editions.
.LINK
Get-Process
.EXAMPLE
> Get-32BitProcess
With elevation: outputs all 32-bit processes.
Without elevation: outputs the current user's 32-bit processes.
.EXAMPLE
> Get-32BitProcess -ID $PID
Implicitly tests if the current process is 32-bit: if it is, information about
the process is output; if not, there's no ouptut.
#>
[CmdletBinding(DefaultParameterSetName='Name')]
param(
[Parameter(ParameterSetName='NameWithUserName', Position=0, ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName='Name', Position=0, ValueFromPipelineByPropertyName=$true)]
[Alias('ProcessName')]
[ValidateNotNullOrEmpty()]
[string[]]
${Name},
[Parameter(ParameterSetName='Id', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName='IdWithUserName', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PID')]
[int[]]
${Id},
[Parameter(ParameterSetName='InputObject', Mandatory=$true, ValueFromPipeline=$true)]
[Parameter(ParameterSetName='InputObjectWithUserName', Mandatory=$true, ValueFromPipeline=$true)]
[System.Diagnostics.Process[]]
${InputObject},
[Parameter(ParameterSetName='IdWithUserName', Mandatory=$true)]
[Parameter(ParameterSetName='NameWithUserName', Mandatory=$true)]
[Parameter(ParameterSetName='InputObjectWithUserName', Mandatory=$true)]
[switch]
${IncludeUserName}
)
if ($env:OS -ne 'Windows_NT') { Throw "This function runs on Windows only." }
if (-not ${env:ProgramFiles(x86)}) { Throw "This function runs on 64-bit editions of Windows only."}
# Define the helper type that provides access to the IsWow64Process
# Windows API function.
# Calling this repeatedly in a session is idempotent, as long as the
# type definition doesn't change.
Add-Type -MemberDefinition @'
[DllImport("kernel32.dll")]
public static extern bool IsWow64Process(System.IntPtr hProcess, [Out] out bool wow64Process);
'@ -Name NativeMethods -Namespace Kernel32
[bool] $is32Bit = $False
$isElevated = ([System.Security.Principal.WindowsPrincipal] [System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Administrators')
if (-not $isElevated) {
Write-Warning "Running without elevation: Output is limited to the current user's 32-bit processes."
}
# Pass the pipeline input / arguments through to Get-Process and collect all
# resulting [System.Diagnostics.Process] instances.
# Note that since we rely on inspecting the .Handle property of
# [System.Diagnostics.Process] instances, we don't support the -FileVersionInfo
# and -Module parameters, because they output objects of different types.
if ($MyInvocation.ExpectingInput) {
# If there's pipeline input, we must remove the pipeline-binding parameters
# from $PSBoundParameters to avoid a collisions.
$null = foreach ($param in 'InputObject', 'Id', 'Name') {
$PSBoundParameters.Remove($param)
}
$processes = $Input | Microsoft.PowerShell.Management\Get-Process @PSBoundParameters
} else {
$processes = Microsoft.PowerShell.Management\Get-Process @PSBoundParameters
}
# Now filter the result objects by removing non-32-bit processes.
[bool] $is32Bit = $false
foreach ($ps in $processes) {
if (-not $ps.Handle) {
# Without elevation, many processes cannot be accessed, and some
# cannot even be accessed with elevation (e.g., 'services')
Write-Verbose "Access to process handle denied: $($ps.Name) ($($ps.ID))"
} elseif (-not ([Kernel32.NativeMethods]::IsWow64Process($ps.Handle, [ref]$is32Bit))) {
Write-Error "IsWow64Process() Windows API call failed for ID $($ps.ID)" # should never happen
} elseif ($is32Bit) { # a 32-bit process: output it
$ps
} else {
Write-Verbose "Not a 32-bit process: $($ps.Name) ($($ps.ID))"
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.