簡體   English   中英

將 Powershell 變量傳遞給 Windows 批處理文件

[英]Passing Powershell variable to Windows Batch file

由於我的項目及其部署方式的限制,我需要在批處理文件中運行 powershell 命令並從 powershell 腳本中回顯變量。 此腳本通過 RS-232 從電視中檢索型號,並以十六進制形式返回型號。

我編寫了腳本並精心將其濃縮為一行運行。 我什至可以在命令行中使用 'powershell -command "[myCondensedScript]"' 並且效果很好

for /F %%a in ('powershell.exe -command "$port = New-Object System.IO.Ports.SerialPort COM1, 9600, none, 8, one;[byte[]] $reqSerial = 1,48,65,48,65,48,54,2,67,50,49,55,3,112,13;[byte[]] $reqModel = 0x01,0x30,0x41,0x30,0x41,0x30,0x36,0x02,0x43,0x32,0x31,0x37,0x03,0x70,0x0D;[byte[]] $response = '';[byte[]] $readData = '';$port.DTREnable = $True;$port.Open();$port.Write($reqModel, 0, $reqModel.Count);$x=0;do {$x++;$readData = $port.ReadChar();If($x -eq 13 -or $x -eq 14 -or $x -eq 15 -or $x -eq 16 -or $x -eq 17 -or $x -eq 18 -or $x -eq 19 -or $x -eq 20 -or $x -eq 21) {$response += $readData;};}while($response.Length -ne 9);$port.Close();$hexResponse = $response.forEach([char]);$hexResponseString = [string]$hexResponse;$hexResponseString = $hexResponseString.replace(' ','');$finalHex = $hexResponseString+0;Write-Host $finalHex;"^; (Get-Variable -ValueOnly -Name finalHex^).value') do set HexCode=%%a

echo %HexCode%

輸出很簡單

   echo +

預期的輸出將是

563332330

我不確定變量缺少什么,因為我對變量和批處理文件不是很熟練。 我在谷歌上進行了廣泛的搜索,發現這個頁面有點幫助https://ss64.com/nt/for.html我只是不明白我如何將 %%a 分配給我想要的確切變量。 任何幫助將不勝感激!

您的命令在封閉的'...'字符串的上下文中未轉義嵌入的'字符,這將不起作用。

相反,使用usebackq解析選項並將命令括在`...` ,這樣可以簡化引用和轉義。

以下示例命令演示了該技術(要在cmd.exe提示符而不是批處理文件中嘗試此操作,請將%%a替換%%a %a ):

for /f "usebackq delims=" %%a in (`
  powershell -c "$finalHex = '0x68 0x69' -replace '0x| '; $finalHex"
`) do set "HexNum=%%a"
echo %HexNum%

上面打印了以下內容,證明嵌入的"..."'...'; 按原樣工作(在使用"..."作為一個整體傳遞給-c ( -Command ) 的 PowerShell 命令的封閉引號的上下文中,這會阻止cmd.exe解釋內容):

6969

使用PowerShell 的 CLI總結usebackq規則

  • 通過PowerShell命令封裝在"..."作為一個整體-c / -Command參數(這是在Windows PowerShell隱含的,但需要在PowerShell中[核心] 6+)。

    • 由於cmd.exe不解釋"..."字符串的內容(除了%...%環境變量引用), cmd.exe元字符(具有特殊句法含義的字符,例如& )可以用作-是。
  • 單引號 ( ' ) 可以按原樣使用。

  • 如果您需要在整個"..."命令字符串中嵌入雙引號 ( " ):

    • 在 PowerShell [Core] 6+ ( pwsh.exe ) 中,使用""
    • 在Windows PowerShell( powershell.exe ),使用\\"" ,但要注意,字符串內部的空格將被歸一化(折疊成一個空格); \\"避免了這種情況,但隨后要求您^ -escape 任何cmd.exe元字符,例如&
for /f "usebackq delims=" %%i in (`
  REM In PowerShell [Core] 6+ (pwsh.exe), use "" instead of \""
  powershell -noprofile -c "(\""hi &    there\"").Replace('i', '@')"
`) do @echo [%%i]

上面的結果(注意規范化的空格;在 PowerShell [Core] 6+ 中使用""這不會發生):

[hi & there]

至於你的具體命令

  • 刪除^ (插入符號),因為不再需要使用`...`引用; 將傳遞給powershell -c的命令作為一個整體包含"..."

  • 防止輸出流的污染以確保只返回感興趣的值,這意味着:

    • 刪除Write-Host命令。

    • $null = ...放在$port.Open()$port.Write(...)$port.Close()調用之前,以確保它們不會隱式創建輸出(有關解釋,請參閱此答案)。

  • 只需使用$finalHex本身作為最后一個發言,以輸出它(不需要(Get-Variable ...)

我解析了它的powershell部分。 最后的兩個插入符號 ^ 對我來說沒有意義。 你能解釋一下它們的要點嗎? 仔細看最后一行。

# Removed " from "$Port below

$port = New-Object System.IO.Ports.SerialPort COM1, 9600, none, 8, one;
[byte[]] $reqSerial = 1,48,65,48,65,48,54,2,67,50,49,55,3,112,13;
[byte[]] $reqModel = 0x01,0x30,0x41,0x30,0x41,0x30,0x36,0x02,0x43,0x32,0x31,0x37,0x03,0x70,0x0D;
[byte[]] $response = '';[byte[]] $readData = '';$port.DTREnable = $True;
$port.Open();
$port.Write($reqModel, 0, $reqModel.Count);$x=0;

do {$x++;$readData = $port.ReadChar();

    If($x -eq 13 -or $x -eq 14 -or $x -eq 15 -or $x -eq 16 -or $x -eq 17 -or $x -eq 18 -or $x -eq 19 -or $x -eq 20 -or $x -eq 21) 
    {$response += $readData;};

}
while($response.Length -ne 9);
$port.Close();

$hexResponse = $response.forEach([char]);
$hexResponseString = [string]$hexResponse;
$hexResponseString = $hexResponseString.replace(' ','');
$finalHex = $hexResponseString+0;
Write-Host $finalHex;"^; (Get-Variable -ValueOnly -Name finalHex^).value

如果這在 powershell 中有效,那么您可以嘗試將其放回您擁有的命令行中。

$port = New-Object System.IO.Ports.SerialPort COM1, 9600, none, 8, one;
[byte[]] $reqSerial = 1,48,65,48,65,48,54,2,67,50,49,55,3,112,13;
[byte[]] $reqModel = 0x01,0x30,0x41,0x30,0x41,0x30,0x36,0x02,0x43,0x32,0x31,0x37,0x03,0x70,0x0D;
[byte[]] $response = '';[byte[]] $readData = '';$port.DTREnable = $True;
$port.Open();
$port.Write($reqModel, 0, $reqModel.Count);
$x=0;

do {$x++;$readData = $port.ReadChar();

    If($x -eq 13 -or $x -eq 14 -or $x -eq 15 -or $x -eq 16 -or $x -eq 17 -or $x -eq 18 -or $x -eq 19 -or $x -eq 20 -or $x -eq 21) 
    {$response += $readData;};

}
while($response.Length -ne 9);
$port.Close();

$hexResponse = $response.forEach([char]);
$hexResponseString = [string]$hexResponse;
$hexResponseString = $hexResponseString.replace(' ','');
$finalHex = $hexResponseString+0;
(Get-Variable -ValueOnly -Name finalHex).value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM