2016-09-30 54 views
0

通常,PowerShell命令可以用分號鏈接。下面打開2個記事本:如何在特定的PowerShell中鏈接命令4命令提示符?

PS> notepad; notepad 

你也可以連接一個更復雜的語句:

PS> Add-Type -AssemblyName System.IO.Compression; ` 
> $src = "C:\aFolder"; $zip="C:\my.zip"; ` 
> [io.compression.zipfile]::CreateFromDirectory($src, $zip) 

鏈式PowerShell命令也可以從一個CMD命令行稱爲:

C:\> powershell notepad; notepad 

This post描述了一種創建.Net 4.0 PowerShell提示的方法,即使.Net 2.0是您OS上的活動框架。你創建一個.cmd腳本,然後運行它。現在您處於.Net 4.0環境中。

鏈接也工作在這個4.0提示:

C:\> ps4.cmd 
PS> notepad; notepad 

而且也從標準的命令提示符工作:

C:\> ps4 notepad; notepad 

This post描述辦法做到Add-Type一個明確的路徑(參考4.0需要來自ps4提示的組件):

Add-Type -Path "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.IO.Compression.FileSystem\v4.0_4.0.0.0__b77a5c561934e089\System.IO.Compression.FileSystem.dll" 

這樣的作品,即使在PS4提示鏈接:

C:\> ps4 
PS> Add-Type -Path "C:\x\System.IO.Compression.FileSystem.dll"; ` 
> $src = "C:\x\xl"; $zip="C:\x\xl.zip"; ` 
> [io.compression.zipfile]::CreateFromDirectory($src, $zip) 

問題:

鏈接上面的語句時,PS4在一個標準的命令提示符(誤差完全在後的底部)啓動失敗
C:\> ps4 Add-Type -Path "C:\x\System.IO.Compression.FileSystem.dll"; $src = "C:\x\xl"; $zip="C:\x\xl.zip"; [io.compression.zipfile]::CreateFromDirectory($src, $zip) 

然而,所有上述方法的工作。爲什麼?我該如何做這項工作?

The term 'C:\x\xl' is not recognized as the name of a cmdlet, function, script 
file, or operable program. Check the spelling of the name, or if a path was 
included, verify that the path is correct and try again. 
At line:1 char:73 
+ Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl <<<< ; $zip=C:\x\xl.zip; 
[io.compression.zipfile]::CreateFromDirectory($src, $zip) 
    + CategoryInfo   : ObjectNotFound: (C:\x\xl:String) [], CommandNotFoundException 
    + FullyQualifiedErrorId : CommandNotFoundException 

The term 'C:\x\xl.zip' is not recognized as the name of a cmdlet, function, 
script file, or operable program. Check the spelling of the name, or if a path 
was included, verify that the path is correct and try again. 
At line:1 char:91 
+ Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl; $zip=C:\x\xl.zip <<<< ; 
[io.compression.zipfile]::CreateFromDirectory($src, $zip) 
    + CategoryInfo   : ObjectNotFound: (C:\x\xl.zip:String) [], CommandNotFoundException 
    + FullyQualifiedErrorId : CommandNotFoundException 

Exception calling "CreateFromDirectory" with "2" argument(s): "The path is not 
of a legal form." 
At line:1 char:138 
+ Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl; $zip=C:\x\xl.zip; 
[io.compression.zipfile]::CreateFromDirectory <<<< ($src, $zip) 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : DotNetMethodException

回答

1

當菊花鏈命令傳遞到powershell.exe時,字符串周圍的雙引號將被刪除。 Add-Type不會受此影響,因爲路徑不包含空格,所以它不需要引號:

Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll # <- this works 

然而,在賦值操作PowerShell需要串加引號,否則會解釋字符串作爲一個命令,並嘗試執行它:

$src = C:\x\xl # <- this would try to run a (non-existent) command 'C:\x\xl' 
       # and assign its output to the variable instead of assigning 
       # the string "C:\x\xl" to the variable 

這是什麼原因導致你觀察到的前兩個錯誤。第三個錯誤是後續錯誤,因爲兩個路徑變量未正確初始化。

您應該能夠通過轉義雙引號,以避免此行爲:

ps4 Add-Type -Path \"C:\x\System.IO.Compression.FileSystem.dll\"; $src = \"C:\x\xl\"; $zip=\"C:\x\xl.zip\"; [io.compression.zipfile]::CreateFromDirectory($src, $zip) 

或用單引號來替換(因爲後者不被CMD視爲引號字符,並因此通過原樣是PowerShell的,它不承認他們是引號字符):

ps4 Add-Type -Path 'C:\x\System.IO.Compression.FileSystem.dll'; $src = 'C:\x\xl'; $zip='C:\x\xl.zip'; [io.compression.zipfile]::CreateFromDirectory($src, $zip) 

然而,而不是解決此問題的工作,我建議創建和運行適當的PowerShell腳本,這樣你就可以完全避免這個問題:

#requires -version 4 
[CmdletBinding()] 
Param(
    [Parameter(Mandatory=$true)] 
    [string]$Path, 
    [Parameter(Mandatory=$true)] 
    [string]$Zipfile, 
) 

Add-Type -Assembly 'System.IO.Compression.FileSystem' | Out-Null 
[IO.Compression.ZipFile]::CreateFromDirectory($Path, $Zipfile) 

該腳本會這樣運行:

powershell.exe -File zip.ps1 -Path "C:\x\xl" -Zipfile "C:\x\xl.zip" 

如果您更改執行策略,以RemoteSignedUnrestricted,改變默認的處理程序.ps1文件,你甚至可以運行這樣的腳本:

zip.ps1 -Path "C:\x\xl" -Zipfile "C:\x\xl.zip" 
+0

真棒!你的解決方案有效:逃避雙引號,或使用單打。雖然我想用一個適當的腳本,但我不明白我能做什麼。我的用例是:我必須用VB的單個語句執行整個過程。我假設如果我在多個語句中調用PS4.cmd,它們將是獨立的會話:在一次調用中添加程序集將無法連接到後續調用。此外,我必須將這些命令嵌入到VB代碼中,因此使用';'鏈接它們似乎比在VB中嵌入腳本更方便,將腳本保存爲批處理文件,然後執行該腳本 - 但我歡迎提供建議。謝謝! –

+0

我把你的答案鏈接到這裏:http://stackoverflow.com/a/39800779/209942 –

相關問題