Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell:确定进程是32位还是64位_Powershell_Powershell 3.0 - Fatal编程技术网

Powershell:确定进程是32位还是64位

Powershell:确定进程是32位还是64位,powershell,powershell-3.0,Powershell,Powershell 3.0,有没有办法确定给定的进程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 I

有没有办法确定给定的进程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位的问题,但它提供了一个方便的提示来确定当前进程是否是32位的

试试这个,这是我知道的最简单的方法。在64位应用程序中,指针的长度为8字节。在32位应用程序中,指针的长度为4位。

基于:

下面是
Get-32bit进程
函数
的源代码,它是一个围绕
Get进程
的包装器,只报告32位进程

注意事项:

  • 仅支持本地进程,因此不支持
    -ComputerName
    参数。参数
    -Module
    -FileVersionInfo
    也不受支持,但您可以使用这些参数通过管道连接到
    Get进程
    调用

  • 测试由不同用户创建的进程的位性需要提升(以管理员身份运行),因此要检查所有32位进程,请使用提升运行。
    如果您在没有提升的情况下运行,系统会警告您,只有当前用户的进程才能成为目标;使用
    -WarningAction SilentlyContinue
    使警告静音

  • 由于32位和64位进程之间的区别仅在64位版本的Windows上才有意义,因此该函数拒绝在32位版本上运行-只需在此处使用
    Get Process

要使用它来解决OP的问题,请使用当前流程的示例(
$PID
):

也就是说,给定一个有效的PID(进程ID),
Get-32bit进程
输出一个表示进程的
[System.Diagnostics.process]
对象,如报告的
Get-process
所示,如果目标进程是32位的;如果是64位进程,则不输出任何内容

要简单列出所有正在运行的32位进程(带提升:系统范围;不带提升:由当前用户创建),请执行以下操作:


Get-32bit进程
源代码

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))"
      }
  }

}
函数Get-32bit进程{
Get-32位进程-ID$PID
隐式测试当前进程是否为32位:如果是,则提供有关
这个过程是输出的;如果不是,就没有输出。
#>
[CmdletBinding(DefaultParameterSetName='Name')]
param(
[参数(ParameterSetName='NameWithUserName',Position=0,ValueFromPipelineByPropertyName=$true)]
[参数(ParameterSetName='Name',Position=0,ValueFromPipelineByPropertyName=$true)]
[别名('ProcessName')]
[ValidateNotNullOrEmpty()]
[字符串[]]
${Name},
[参数(ParameterSetName='Id',必填=$true,ValueFromPipelineByPropertyName=$true)]
[参数(ParameterSetName='IdWithUserName',必填=$true,ValueFromPipelineByPropertyName=$true)]
[别名('PID')]
[int[]
${Id},
[参数(ParameterSetName='InputObject',必填=$true,ValueFromPipeline=$true)]
[参数(ParameterSetName='InputObjectWithUserName',必填=$true,ValueFromPipeline=$true)]
[系统.诊断.过程[]]
${InputObject},
[参数(ParameterSetName='IdWithUserName',必填=$true)]
[参数(ParameterSetName='NameWithUserName',必填=$true)]
[参数(ParameterSetName='InputObject WithUserName',必填项=$true)]
[开关]
${IncludeUserName}
)
如果($env:OS-ne'Windows\u NT'){Throw“此函数仅在Windows上运行。”}
if(-not${env:ProgramFiles(x86)}){Throw“此函数仅在64位版本的Windows上运行。”}
#定义提供对ISWOW64进程访问权限的帮助器类型
#windowsapi函数。
#在会话中重复调用它是幂等的,只要
#类型定义不会更改。
添加类型-MemberDefinition@'
[DllImport(“kernel32.dll”)]
公共静态外部bool IsWow64Process(System.IntPtr hProcess,[Out]Out bool wow64Process);
'@-Name NativeMethods-Namespace Kernel32
[bool]$is32位=$False
$isElevated=([System.Security.Principal.WindowsPrincipal][System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Administrators'))
如果(-未提取$i){
写入警告“在没有提升的情况下运行:输出仅限于当前用户的32位进程。”
}
#传递管道输入/参数以获取进程并收集所有
#结果[System.Diagnostics.Process]实例。
#请注意,由于我们依赖于检查的.Handle属性
#[System.Diagnostics.Process]实例,我们不支持-FileVersionInfo
#和-模块参数,因为它们输出不同类型的对象。
if($MyInvocation.ExpectingInput){
#如果有管道输入,我们必须删除管道绑定参数
#从$PSBoundParameters开始,以避免碰撞。
$null=foreach('InputObject','Id','Name'中的参数){
$PSBoundParameters.Remove($param)
}
$processs=$Input | Microsoft.PowerShell.Management\Get Process@PSBoundParameters
}否则{
$processs=Microsoft.PowerShell.Management\Get Process@PSBoundParameters
}
#现在,通过删除非32位进程来过滤结果对象。
[bool]$is32位=$false
foreach($进程中的ps){
如果(-非$ps.Handle){
#没有提升,许多进程无法访问,有些进程
#甚至不能通过提升访问(例如,“服务”)
详细写入“拒绝访问进程句柄:$($ps.Name)($($ps.ID))”
}elseif(-not([Kernel32.NativeMethods]::IsWow64Process($ps.Handle,[ref]$is32位))){
写入错误“ID$($ps.ID)的IsWow64Process()Windows API调用失败”#不应发生
}elseif($is32位){一个32位进程:输出它
$ps
}否则{
西铁
$is32Bit = [bool] (Get-32BitProcess -ID $PID)
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))"
      }
  }

}