我有从this question的答案获得的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%
运行此批处理文件时,会报告几个错误:
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的新手,而且它的多重特性一直困扰着我......
在批处理文件中编写此PS代码的正确方法是什么?如果还包括对问题原因的简单解释,我将不胜感激......
答案 0 :(得分:4)
双引号文字必须转义为\"
@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
答案 1 :(得分:1)
前一段时间有a topic on 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
答案 2 :(得分:0)
我会在这里选择-EncodedCommand
选项。您只需对整个powershell脚本进行Base64编码,然后将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