本文介绍了针对 powershell 的 x64 与 x86 可变性进行编程的最佳方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有几个脚本用于安装和配置支持我们维护的系统的依赖项.我们在建立开发、测试、演示、训练、生产等环境的任何时候运行这些.我们经常发现我们必须处理 x64 与 x86 架构,特别是在涉及 powershell 脚本的地方.

We have several scripts we use to install and configure the dependencies backing the systems we maintain. We run these anytime we establish a dev, test, demo, train, prod, etc. environment. We often find that we have to deal with x64 vs. x86 architecture, especially where the powershell scripts are concerned.

例如,我有一个脚本,它使用 Windows Installer PowerShell 扩展 来确定程序/补丁已安装.如果不显式调用 PowerShell (x86),该脚本无法在 x64 环境中运行,默认情况下,PowerShell (x86) 不在路径中.当我们将这些脚本移植到 x64 平台时,最好维护一组脚本,这些脚本可以在两种架构的 powershell 中运行,并且仅在需要时调用 x86 代码.

For example, I have a script that uses the Windows Installer PowerShell Extensions to determine if a program/patch has been installed. The script doesn't work in an x64 environment without explicitly invoking PowerShell (x86), which, isn't in the path by default. As we port these scripts to the x64 platform it would be great to maintain a single set of scripts that work in powershell on both architectures and only invoke x86 code when needed.

有人知道这样做的策略吗?

Does anyone know of a strategy for doing this?

推荐答案

我的配置脚本经常遇到这个问题.我采取的基本方法是

I run into this issue a lot with my configuration scripts. The basic approach I take is to

  1. 使用几个函数来测试我是否在 64 位环境中(http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx)
  2. 根据特定脚本的需要调用 x86/x64 PowerShell

不幸的是,很多都是以蛮力方式完成的.每个依赖于 x86/x64 的特定配置条目本质上都有 2 个代码路径(每个架构一个).

Unfortunately a lot of this is done in a brute force manner. Each particular configuration entry that is x86/x64 dependent essentially has 2 code paths (one for each architecture).

我能做的唯一真正的例外是测试磁盘上是否存在某些程序.我有一个方便的函数 (Get-ProgramFiles32),可以轻松测试程序.

The only real exception I've been able to make is to test for the existince of certain programs on disk. I have a handy function (Get-ProgramFiles32) which makes it easy to test for programs.

if ( test-path (join-path Get-ProgramFiles32 "subversion") ) { ...

以下是我在公共库中处理 32/64 位差异的所有辅助函数.

Here are all of the helper functions that I have in my common library that deal with 32/64 bit differences.

# Get the path where powershell resides.  If the caller passes -use32 then 
# make sure we are returning back a 32 bit version of powershell regardless
# of the current machine architecture
function Get-PowerShellPath() {
    param ( [switch]$use32=$false,
            [string]$version="1.0" )

    if ( $use32 -and (test-win64machine) ) {
        return (join-path $env:windir "syswow64\WindowsPowerShell\v$version\powershell.exe")
    }

    return (join-path $env:windir "System32\WindowsPowerShell\v$version\powershell.exe")
}


# Is this a Win64 machine regardless of whether or not we are currently 
# running in a 64 bit mode 
function Test-Win64Machine() {
    return test-path (join-path $env:WinDir "SysWow64") 
}

# Is this a Wow64 powershell host
function Test-Wow64() {
    return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432)
}

# Is this a 64 bit process
function Test-Win64() {
    return [IntPtr]::size -eq 8
}

# Is this a 32 bit process
function Test-Win32() {
    return [IntPtr]::size -eq 4
}

function Get-ProgramFiles32() {
    if (Test-Win64 ) {
        return ${env:ProgramFiles(x86)}
    }

    return $env:ProgramFiles
}

function Invoke-Admin() {
    param ( [string]$program = $(throw "Please specify a program" ),
            [string]$argumentString = "",
            [switch]$waitForExit )

    $psi = new-object "Diagnostics.ProcessStartInfo"
    $psi.FileName = $program 
    $psi.Arguments = $argumentString
    $psi.Verb = "runas"
    $proc = [Diagnostics.Process]::Start($psi)
    if ( $waitForExit ) {
        $proc.WaitForExit();
    }
}

# Run the specified script as an administrator
function Invoke-ScriptAdmin() {
    param ( [string]$scriptPath = $(throw "Please specify a script"),
            [switch]$waitForExit,
            [switch]$use32=$false )

    $argString = ""
    for ( $i = 0; $i -lt $args.Length; $i++ ) {
        $argString += $args[$i]
        if ( ($i + 1) -lt $args.Length ) {
            $argString += " "
        }
    }

    $p = "-Command & "
    $p += resolve-path($scriptPath)
    $p += " $argString" 

    $psPath = Get-PowershellPath -use32:$use32
    write-debug ("Running: $psPath $p")
    Invoke-Admin $psPath $p -waitForExit:$waitForExit
}

这篇关于针对 powershell 的 x64 与 x86 可变性进行编程的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 18:33