在.BATch文件中将一个小的PS脚本转换成一个长行

我从这个问题的答案中得到了这个PowerShell代码; 它显示PS代码运行的cmd.exe窗口的位置/尺寸:

$WindowFunction,$RectangleStruct = Add-Type -MemberDefinition @' [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } '@ -Name "type$([guid]::NewGuid() -replace '-')" -PassThru $MyWindowHandle = (Get-Process -Id (Get-WmiObject Win32_Process -Filter "ProcessId=$PID").ParentProcessId).MainWindowHandle $WindowRect = New-Object -TypeName $RectangleStruct.FullName $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect) Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom 

当我从命令行在.ps1脚本中运行此代码时,它可以正常工作:

 C:\Users\Antonio\Documents\test> powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process; .\test.ps1 26 -7 943 738 

我想将这段代码插入到.BATch文件中,以便没有单独的.ps1文件,所以我必须将相同的代码作为参数写入powershell命令。 但是,为了保持可读性,我想在.bat文件中使用单独的行,并用批处理字符^终止每一行。 这是我第一次尝试:

 @echo off PowerShell ^ $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition '^ [DllImport("user32.dll", SetLastError = true)] ^ [return: MarshalAs(UnmanagedType.Bool)] ^ public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); ^ [StructLayout(LayoutKind.Sequential)] ^ public struct RECT ^ { ^ public int Left; ^ public int Top; ^ public int Right; ^ public int Bottom; ^ } ^ ' -Name "type$([guid]::NewGuid() -replace '-')" -PassThru; ^ $MyWindowHandle = (Get-Process -Id (Get-WmiObject Win32_Process -Filter "ProcessId=$PID").ParentProcessId).MainWindowHandle; ^ $WindowRect = New-Object -TypeName $RectangleStruct.FullName; ^ $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect); ^ Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom %End PowerShell% 

当我运行这个batch file时,会报告几个错误:

 C:\Users\Antonio\Documents\test> test.bat Add-Type : c:\Users\Antonio\AppData\Local\Temp\yhd4ckqv.0.cs(8) : El nombre 'user32' no existe en el contexto actual c:\Users\Antonio\AppData\Local\Temp\yhd4ckqv.0.cs(7) : { c:\Users\Antonio\AppData\Local\Temp\yhd4ckqv.0.cs(8) : >>> [DllImport(user32.dll, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } c:\Users\Antonio\AppData\Local\Temp\yhd4ckqv.0.cs(9) : En línea: 1 Carácter: 36 + $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition ' [DllImport(user3 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ + CategoryInfo : InvalidData: (c:\Users\Antoni...contexto actual: CompilerError) [Add-Type], Exception + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands. AddTypeCommand Add-Type : No se puede agregar el tipo. Hubo errores de compilación. En línea: 1 Carácter: 36 + $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition ' [DllImport(user3 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ and a long et cetera.... 

我试图将撇号传递到下面的行,用引号和反义词来改变撇号,在每行开始处删除额外的空格以及其他一些修改,但是我找不到写这段代码的正确方法。 我用相同的方式写了几个PS代码段,之前比这个更大,完全没有问题。 虽然我是一个有经验的程序员,但我是PowerShell的新手,它的多重特质一直困扰着我…

在batch file中写这个PS代码的正确方法是什么? 如果对问题原因的简单解释也包括在内,我将不胜感激。

双引号文字必须转义为\"

 @echo off PowerShell^ $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition '^ [DllImport(\"user32.dll\", SetLastError = true)]^ [return: MarshalAs(UnmanagedType.Bool)]^ public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);^ [StructLayout(LayoutKind.Sequential)]^ public struct RECT^ {^ public int Left;^ public int Top;^ public int Right;^ public int Bottom;^ }^ ' -Name \"type$([guid]::NewGuid() -replace '-')\" -PassThru;^ $MyWindowHandle = (Get-Process -Id (^ Get-WmiObject Win32_Process -Filter \"ProcessId=$PID\"^ ).ParentProcessId).MainWindowHandle;^ $WindowRect = New-Object -TypeName $RectangleStruct.FullName;^ $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect);^ Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom 

前段时间有一个关于DosTips的话题来解决这个问题。 你可以用一个简单的头文件来创建批量/ Powershell混合:

 <# : :: Header to create Batch/PowerShell hybrid @echo off setlocal set "POWERSHELL_BAT_ARGS=%*" if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%" endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )" :: Any batch code that gets run after your PowerShell goes here goto :EOF #> 

只需在#>之后抛出Powershell代码,并将该文件保存为常规.bat脚本。 在你的情况下:

 <# : :: Header to create Batch/PowerShell hybrid @echo off setlocal set "POWERSHELL_BAT_ARGS=%*" if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%" endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )" goto :EOF #> $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition @' [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } '@ -Name "type$([guid]::NewGuid() -replace '-')" -PassThru $MyWindowHandle = (Get-Process -Id (Get-WmiObject Win32_Process -Filter "ProcessId=$PID").ParentProcessId).MainWindowHandle $WindowRect = New-Object -TypeName $RectangleStruct.FullName $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect) Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom 

我会去这里的-EncodedCommand选项。 您只需对Base64编码整个powershell脚本,然后将Base64字符串作为参数传递给powershell.exe

(假设脚本在这里: C:\Path\To\Script.ps1

 PS C:\> $ScriptText = Get-Content C:\Path\To\Script.ps1 -Raw PS C:\> $ScriptBytes = [System.Text.Encoding]::Unicode.GetBytes($ScriptText) PS C:\> $EncCommand = [System.Convert]::ToBase64String($ScriptBytes) 

$EncCommand现在包含Base64编码命令,可以在cmd.exe (或者你的批处理文件)中使用:

 C:\>powershell -EncodedCommand JABXAGkAbgBkAG8AdwBGAHUAbgBjAHQAaQBvAG4ALAAkAFIAZQBjAHQAYQBuAGcAbABlAFMAdAByAHUAYwB0ACAAPQAgAEEAZABkAC0AVAB5A HAAZQAgAC0ATQBlAG0AYgBlAHIARABlAGYAaQBuAGkAdABpAG8AbgAgAEAAJwANAAoAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAdQBzAGUAcgAzADIALgBkAGwAbAAiACwAIABTAGUAd ABMAGEAcwB0AEUAcgByAG8AcgAgAD0AIAB0AHIAdQBlACkAXQANAAoAWwByAGUAdAB1AHIAbgA6ACAATQBhAHIAcwBoAGEAbABBAHMAKABVAG4AbQBhAG4AYQBnAGUAZABUAHkAcABlA C4AQgBvAG8AbAApAF0ADQAKAHAAdQBiAGwAaQBjACAAcwB0AGEAdABpAGMAIABlAHgAdABlAHIAbgAgAGIAbwBvAGwAIABHAGUAdABXAGkAbgBkAG8AdwBSAGUAYwB0ACgASQBuAHQAU AB0AHIAIABoAFcAbgBkACwAIAByAGUAZgAgAFIARQBDAFQAIABsAHAAUgBlAGMAdAApADsADQAKAFsAUwB0AHIAdQBjAHQATABhAHkAbwB1AHQAKABMAGEAeQBvAHUAdABLAGkAbgBkA C4AUwBlAHEAdQBlAG4AdABpAGEAbAApAF0ADQAKAHAAdQBiAGwAaQBjACAAcwB0AHIAdQBjAHQAIABSAEUAQwBUAA0ACgB7AA0ACgAgACAAIAAgAHAAdQBiAGwAaQBjACAAaQBuAHQAI ABMAGUAZgB0ADsADQAKACAAIAAgACAAcAB1AGIAbABpAGMAIABpAG4AdAAgAFQAbwBwADsADQAKACAAIAAgACAAcAB1AGIAbABpAGMAIABpAG4AdAAgAFIAaQBnAGgAdAA7AA0ACgAgA CAAIAAgAHAAdQBiAGwAaQBjACAAaQBuAHQAIABCAG8AdAB0AG8AbQA7AA0ACgB9AA0ACgAnAEAAIAAtAE4AYQBtAGUAIAAiAHQAeQBwAGUAJAAoAFsAZwB1AGkAZABdADoAOgBOAGUAd wBHAHUAaQBkACgAKQAgAC0AcgBlAHAAbABhAGMAZQAgACcALQAnACkAIgAgAC0AUABhAHMAcwBUAGgAcgB1AA0ACgANAAoAJABNAHkAVwBpAG4AZABvAHcASABhAG4AZABsAGUAIAA9A CAAKABHAGUAdAAtAFAAcgBvAGMAZQBzAHMAIAAtAEkAZAAgACgARwBlAHQALQBXAG0AaQBPAGIAagBlAGMAdAAgAFcAaQBuADMAMgBfAFAAcgBvAGMAZQBzAHMAIAAtAEYAaQBsAHQAZ QByACAAIgBQAHIAbwBjAGUAcwBzAEkAZAA9ACQAUABJAEQAIgApAC4AUABhAHIAZQBuAHQAUAByAG8AYwBlAHMAcwBJAGQAKQAuAE0AYQBpAG4AVwBpAG4AZABvAHcASABhAG4AZABsA GUADQAKAA0ACgAkAFcAaQBuAGQAbwB3AFIAZQBjAHQAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAJABSAGUAYwB0AGEAbgBnAGwAZQBTAHQAc gB1AGMAdAAuAEYAdQBsAGwATgBhAG0AZQANAAoAJABuAHUAbABsACAAPQAgACQAVwBpAG4AZABvAHcARgB1AG4AYwB0AGkAbwBuADoAOgBHAGUAdABXAGkAbgBkAG8AdwBSAGUAYwB0A CgAJABNAHkAVwBpAG4AZABvAHcASABhAG4AZABsAGUALABbAHIAZQBmAF0AJABXAGkAbgBkAG8AdwBSAGUAYwB0ACkADQAKAA0ACgBXAHIAaQB0AGUALQBIAG8AcwB0ACAAJABXAGkAb gBkAG8AdwBSAGUAYwB0AC4ATABlAGYAdAAgACQAVwBpAG4AZABvAHcAUgBlAGMAdAAuAFQAbwBwACAAJABXAGkAbgBkAG8AdwBSAGUAYwB0AC4AUgBpAGcAaAB0ACAAJABXAGkAbgBkA G8AdwBSAGUAYwB0AC4AQgBvAHQAdABvAG0A 100 -2 1257 748