Pergunta

Existe uma maneira de determinar se um determinado ID de processo é para um processo de 32 ou 64 bits?Estou usando o Powershell v3.0

Foi útil?

Solução

Experimente isto:

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

Deve haver uma verificação aqui para garantir que o sistema operacional seja de 64 bits, caso contrário todos os processos seriam de 32 bits.

Outras dicas

Nota do editor:Embora esta postagem não responda à pergunta - que é determinar se um dado processo é de 32 bits - fornece uma dica útil para determinar se o atual um é.

Tente isso, esta é praticamente a maneira mais fácil que conheço de fazer isso.Em aplicativos de 64 bits, os ponteiros têm 8 bytes de comprimento.Em aplicativos de 32 bits, os ponteiros têm 4 bits.

If([IntPtr]::Size -eq 4)
{
    Write-Host "32 bit"
}
Else
{
    Write-Host "64 bit"
}

Construindo em A excelente solução de Keith Hill:

Abaixo está o código fonte do Get-32BitProcess função, um invólucro ao redor Get-Process que relata apenas processos de 32 bits.

Ressalvas:

  • Apenas local processos são suportados, então o -ComputerName parâmetro não é suportado.Parâmetros -Module e -FileVersionInfo também não são suportados, mas você pode simplesmente canalizar para um Get-Process chame com esses parâmetros.

  • Testando o número de bits de um processo criado por um usuário diferente requer elevação (executando como administrador), para examinar todos Processos de 32 bits, executados com elevação.
    Se você executar sem elevação, será avisado de que apenas os processos do usuário atual poderão ser direcionados;usar -WarningAction SilentlyContinue para silenciar o aviso.

  • Como a distinção entre processos de 32 e 64 bits só faz sentido nas edições de 64 bits do Windows, a função se recusa a ser executada nas edições de 32 bits - basta usar Get-Process lá.

Para utilizá-lo para resolver o problema do OP, usando o exemplo do processo atual ($PID):

$is32Bit = [bool] (Get-32BitProcess -ID $PID)

Ou seja, dado um PID válido (ID do processo), Get-32BitProcess produz um [System.Diagnostics.Process] objeto que representa o processo, conforme relatado Get-Process se o processo de destino é de 32 bits;se for um processo de 64 bits, nada é saída.

Para simplesmente listar todos os processos de 32 bits em execução (com elevação:No âmbito do sistema;sem elevação:criado pelo usuário atual):

Get-32BitProcess

Get-32BitProcess Código fonte:

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

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top