2012-01-04 17 views
7

Tôi đang cố gắng thực hiện công việc ở chế độ nền .exe có thông số và đích đến có dấu cách. Ví dụ:Công việc cơ bản ở Powershell

$exec = "C:\Program Files\foo.exe" 

và tôi muốn chạy này với các thông số:

foo.exe /param1 /param2, etc. 

Tôi biết rằng Start-Job thực hiện điều này nhưng tôi đã cố gắng tấn kết hợp khác nhau và nó hoặc mang lại cho tôi một lỗi vì khoảng trắng hoặc vì các tham số. Ai đó có thể giúp tôi với cú pháp ở đây? Tôi cần giả định rằng $exec là đường dẫn của tệp thực thi vì nó là một phần của tệp cấu hình và có thể thay đổi sau này.

Trả lời

8

Một cách để thực hiện việc này là sử dụng script block với khối tham số.

Nếu có một đối số duy nhất có khoảng trống trong đó, chẳng hạn như đường dẫn tệp/thư mục, nó sẽ được trích dẫn để coi đó là một mục duy nhất. Các đối số là một mảng được truyền vào khối tập lệnh.

Ví dụ này sử dụng khối tập lệnh nhưng bạn cũng có thể sử dụng tập lệnh PowerShell sử dụng tham số -FilePath của lệnh ghép ngắn Start-Job thay vì tham số -ScriptBlock.

Dưới đây là một ví dụ mà có lẽ với không gian:

$scriptBlock = { 
    param (
     [string] $Source, 
     [string] $Destination 
    ) 
    $output = & xcopy $Source $Destination 2>&1 
    return $output 
} 

$job = Start-Job -scriptblock $scriptBlock -ArgumentList 'C:\My Folder', 'C:\My Folder 2' 
Wait-Job $job 
Receive-Job $job 

Dưới đây là một ví dụ sử dụng $args built-in biến thay vì param khối.

$scriptBlock = { 
    $output = & xcopy $args 2>&1 
    return $output 
} 

$path1 = "C:\My Folder" 
$path2 = "C:\My Folder 2" 

"hello world" | Out-File -FilePath "$path1\file.txt" 

$job = Start-Job -scriptblock $scriptBlock -ArgumentList $path1, $path2 
Wait-Job $job 
Receive-Job $job 
+0

Cảm ơn sự giúp đỡ! 2> & 1 có nghĩa là gì? – Brian

+0

@Brian Ah yes sẽ chuyển hướng luồng lỗi chuẩn (2) tới luồng tiêu chuẩn (1). Điều này đảm bảo bạn sẽ nhận được tất cả văn bản từ tập tin thực thi từ lệnh 'Receive-Job'.Thông thường những gì tôi làm trong công việc nền là nắm bắt đầu ra của một tập tin thực thi '$ out = xcopy $ a $ b 2> & 1' rồi kiểm tra xem mã thoát (' $ LASTEXITCODE') có khác không và nếu có thì văn bản dưới dạng thông báo ngoại lệ: 'ném $ out'. –

3

Bí quyết của Andy thường hoạt động rất tốt. Nếu bạn có bộ thông số, hoặc nếu không muốn di chuyển thông tin phức tạp vào công việc, bạn cũng có thể thử kỹ thuật này:

$jobArgs = @{Source="foo"; Destination="bar"} 
$jobArgs |Export-CliXml -Path $env:\Temp\MyArgs.clixml 

và trong công việc ...

Start-Job { 
.... $jobArgs = Import-CliXml -Path $env:\Temp\MyArgs.clixml 
} | Wait-Job | Receive-Job 

tôi sử dụng cả hai phương pháp thường xuyên .

tôi sử dụng các thông số -ArgumentList/ScriptBlock khi:

  • Tôi không đối phó với tham số đặt
  • Tôi đang sử dụng In-Memory Job (như khả năng -AsJob trong ShowUI hoặc WPK), nơi các đối số là đối tượng thực, và họ không thể chết
  • tôi đang chạy trong một bối cảnh sử dụng nơi tôi có thể chạy một công việc, nhưng không thể lưu trữ vào đĩa (máy chủ web, các phòng thí nghiệm phù hợp tiêu chuẩn ISO, vv)

Nếu tôi cần comp lex đối số, và họ không cần phải được thông qua trong bộ nhớ (hoặc nó nếu không thuận tiện để có chúng trên đĩa sau này), tôi sẽ sử dụng cách tiếp cận hashtable.

Hy vọng điều này sẽ giúp