[英]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
元字符(具有特殊句法含義的字符,例如&
)可以用作-是。 單引號 ( '
) 可以按原樣使用。
如果您需要在整個"..."
命令字符串中嵌入雙引號 ( "
):
pwsh.exe
) 中,使用""
。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.