2013-05-23 2 views
1

Я автоматизирую сборку устаревшего приложения MS Access, и на одном из этапов я пытаюсь выполнить исполняемый файл Access (.ADE). Я придумал следующий код, который хранится в файле (PSLibrary.ps1):Выполнение сценария Powershell из командной строки с указанными параметрами

Add-Type -AssemblyName Microsoft.Office.Interop.Access 

function Access-Compile { 
param (
    [Parameter(Mandatory=$TRUE,Position=1)][string]$source, 
    [Parameter(Mandatory=$TRUE,Position=2)][string]$destination 
) 
    Write-Output "Starting MS Access" 
    $access = New-Object -ComObject Access.Application 
    $access.Visible = $FALSE 
    $access.AutomationSecurity = 1 

    if (!(Test-Path $source)) { Throw "Source '$source' not found" } 
    if ((Test-Path $destination)) { 
     Write-Output "File '$destination' already exists - deleting..." 
     Remove-Item $destination 
    } 

    Write-Output "Compiling '$source' to '$destination'" 
    $result = $access.SysCmd(603, $source, $destination) 

    $result 

    Write-Output "Exiting MS Access" 
    $access.quit() 
} 

Если я иду в PowerShell ISE и запустите команду ниже, то все работает отлично, и ожидаемые результаты создаются:

PS C:>& "C:\Temp\PSLibrary.ps1" 
PS C:>Access-Compile "C:\Working\Project.adp" "C:\Working\Project.ade" 

Однако, я не могу показаться, чтобы создать правильные фокусы, чтобы получить это работает из командной строки, как я бы в автоматизированной сборке. Например,

powershell.exe -command "& \"C:\\Temp\\PSLibrary.ps1\" Access-Compile \"C:\\Temp\\Project.adp\" \"C:\\Temp\\Project.ade\"" 

Что я делаю неправильно?

ответ

0

PowerShell, как Bash может принимать одинарные или двойные кавычки

PS C:\Users\Steven> echo "hello" 
hello 
PS C:\Users\Steven> echo 'hello' 
hello 

это может облегчить некоторые из головной боли, и я думаю, что вы можете использовать буквенные символы обратной косой черты, не избежать.

Чтобы запустить PowerShell, выберите

Start MenuПрограммыАксессуары Windows PowershellWindows Powershell

+0

Проблема, с которой я сталкиваюсь, не проявляется при запуске из ISE Powershell; это когда я пытаюсь запустить его из CMD. –

+0

Как мне сделать это как часть автоматической сборки? Это и есть цель моего вопроса. –

1

Для сложных параметров, вы можете использовать параметр Powershell в -EncodedCommand. Он будет принимать строчную кодировку Base64. Для котировок, слэшей и т. Д. Не требуется экранирование.

Рассмотрим тестовую функцию, которая будет печатать свои параметры. Например,

function Test-Function { 
param (
    [Parameter(Mandatory=$TRUE,Position=1)][string]$source, 
    [Parameter(Mandatory=$TRUE,Position=2)][string]$destination 
) 
    write-host "src: $source" 
    write-host "dst: $destination" 
} 

Создайте команду для загрузки сценария и некоторых параметров. Таким образом,

# Load the script and call function with some parameters 
. C:\Temp\Calling-Test.ps1; Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`"" 

После синтаксиса команды ОК, закодируйте его в форме Base64. Таким образом,

[System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes('. C:\Temp\Calling-Test.ps1; Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`""')) 

Вы получите строку Base64. Таким образом,

LgAgAEMAOgBcAFQAZQBtAHAAXABDAGEAbABsAGkAbgBnAC0AVABlAHMAdAAuAHAAcwAxADsAIAAgAFQAZQBzAHQALQBGAHUAbgBjAHQAaQBvAG4AIAAiAHMAbwBtAGUAXABzAHAAZQBjAGkAYQBsADoAYwBoAGEAcgBhAGMAdABlAHIAcwA/ACIAIAAiAGAAIgBjADoAXABtAHkAIABwAGEAdABoAFwAdwBpAHQAaABcAHMAcABhAGMAZQBzACAAdwBpAHQAaABpAG4ALgBlAHgAdABgACIAIgA= 

Наконец, запустите Powershell и передайте закодированную строку в качестве параметра. Таким образом,

# The parameter string here is abreviated for readability purposes. 
# Don't do this in production 
C:\>powershell -encodedcommand LgAgA... 
Output 
src: some\special:characters? 
dst: "c:\my path\with\spaces within.ext" 

Если вы захотите поменять кодировку Base64, передайте ее в метод декодирования. Таким образом,

$str = " LgAgA..." 
[Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($str)) 
# Output 
. C:\Temp\Calling-Test.ps1; Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`"" 
+0

С риском задать глупый вопрос, как мне создать закодированную команду из командной строки DOS? –

+0

У вас нет.Используйте команду Powershell для создания команды. – vonPryz

+0

Это практично при запуске автоматической сборки, где параметры могут отличаться от сборки для сборки? \ –