Question

Est-il un moyen pour déterminer si un ID de processus donné est un 32 ou un 64 bits processus?Je suis à l'aide de Powershell v3.0

Était-ce utile?

La solution

Essayez ceci:

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

Il devrait y avoir une chèque ici pour que le système d'exploitation soit 64 bits, sinon tous les processus seraient 32 bits.

Autres conseils

note de l'éditeur : tant que cet article ne répond pas à la question - qui doit déterminer si un processus donné est 32 bits - il fournit une pratique pratiqueConseil pour déterminer si le courant l'un est.

Essayez ceci, c'est à peu près le moyen le plus simple que je connaisse de le faire.Dans 64 bits, les pointeurs d'applications bits sont de 8 octets longs.En 32 bits, les points d'application sont de 4 bits longs.

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

Bâtiment sur Keith Hill est une excellente solution:

Ci-dessous le code source de la Get-32BitProcess la fonction, un wrapper autour de Get-Process que les rapports de processus 32 bits uniquement.

Mises en garde:

  • Seulement local les processus sont pris en charge, de sorte que le -ComputerName paramètre n'est pas pris en charge.Paramètres -Module et -FileVersionInfo ne sont pas pris en charge, mais vous pouvez tout tuyau à un Get-Process appel avec ces paramètres.

  • Test le nombre de bits d'un processus créé par un utilisateur différent nécessite élévation (exécution en tant qu'administrateur), afin d'examiner tous Les processus 32 bits, exécutez avec l'altitude.
    Si vous exécutez sans élévation, vous êtes averti que seul l'utilisateur actuel du processus peuvent être ciblés;utilisation -WarningAction SilentlyContinue le silence de l'avertissement.

  • Puisque la distinction entre les versions 32 bits et 64 bits des processus n'a de sens que sur les éditions 64 bits de Windows, la fonction refuse de s'exécuter sur 32 bits en cours de support: il suffit d'utiliser Get-Process il n'.

De l'utiliser pour résoudre le cas des OP problème, en utilisant l'exemple de l'actuel processus ($PID):

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

C'est, compte tenu valide PID (process ID), Get-32BitProcess les sorties d'un [System.Diagnostics.Process] objet représentant le processus, tel que rapporté Get-Process si le processus cible est de 32 bits;si c'est un processus 64 bits, rien est sortie.

Pour tout simplement la liste de tous les processus 32 bits (avec l'altitude:à l'échelle du système;sans élévation:créé par l'utilisateur en cours):

Get-32BitProcess

Get-32BitProcess le code source:

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top