Add-Type
方法从 Powershell 脚本读取当前 Windows 控制台模式时遇到错误:
$MethodDefinitions = @'
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
'@
$Kernel32 = Add-Type -MemberDefinition $MethodDefinitions -Name 'Kernel32' -Namespace 'Win32' -PassThru
$hConsoleHandle = $Kernel32::GetStdHandle(-11) # STD_OUTPUT_HANDLE
$lpMode = 0
$Kernel32::GetConsoleMode($hConsoleHandle, $lpMode)
但是我收到以下警告和错误:
WARNING: The generated type defines no public methods or properties.
Method invocation failed because [Win32.Kernel32] does not contain a method named 'GetStdHandle'.
At C:\Users\John\get_console_mode.ps1:8 char:1
+ $hConsoleHandle = $Kernel32::GetStdHandle(-11) # STD_OUTPUT_HANDLE
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [Win32.Kernel32] does not contain a method named 'GetConsoleMode'.
At C:\Users\John\get_console_mode.ps1:10 char:1
+ $Kernel32::GetConsoleMode($hConsoleHandle, $lpMode)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
知道我做错了什么吗?
更新:根据已接受的答案,这里是更正后的代码:
$MethodDefinitions = @'
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
'@
$Kernel32 = Add-Type -MemberDefinition $MethodDefinitions -Name 'Kernel32' -Namespace 'Win32' -PassThru
$hConsoleHandle = $Kernel32::GetStdHandle(-11) # STD_OUTPUT_HANDLE
$mode = 0
$Kernel32::GetConsoleMode($hConsoleHandle, [ref]$mode)
尝试使用以下方法定义(我刚刚添加了公共访问修饰符)
$MethodDefinitions = @'
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
'@
我将用这个例子补充这里的解决方案。
每个人都可以按照自己的方式实现参数的传递,比如传递一个模式名称,也可以设置 禁用/启用/反转/检查
$MethodDefinitions = @'
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint lpMode);
public const int STD_INPUT_HANDLE = -10;
public const int STD_OUTPUT_HANDLE = -11;
public const int ENABLE_PROCESSED_INPUT = 0x0001;
public const int ENABLE_PROCESSED_OUTPUT = 0x0001;
'@
$WinAPI = Add-Type -MemberDefinition $MethodDefinitions -Name 'WinAPI' -Namespace 'Win32' -PassThru
$hConsoleHandle = $WinAPI::GetStdHandle($WinAPI::STD_INPUT_HANDLE)
$mode=$WinAPI::ENABLE_PROCESSED_INPUT
$WinAPI::GetConsoleMode($hConsoleHandle, [ref]$mode)
if($true){
# disable
$dmi = -bnot $WinAPI::ENABLE_PROCESSED_INPUT
$mode = $mode -band $dmi
} else {
#enable
$dmi = $WinAPI::ENABLE_PROCESSED_INPUT
$mode = $mode -bor $dmi
}
# inversion - enabled or disabled
# $mode = $mode -bxor $WinAPI::ENABLE_PROCESSED_INPUT
# check
$mode -eq ($mode -bor $WinAPI::ENABLE_PROCESSED_INPUT)
$WinAPI::SetConsoleMode($hConsoleHandle, $mode)