无效CONSOLE_SCREEN_BUFFER_INFOEX; GetConsoleScreenBufferInfoEx (kernel32)
Invalid CONSOLE_SCREEN_BUFFER_INFOEX; GetConsoleScreenBufferInfoEx (kernel32)
GetConsoleScreenBufferInfoEx 无效 return 值
我正在尝试更改控制台的调色板。为了完成这项工作,我首先需要 Get
我的 ConsoleScreenBufferInfoEx
然后 Set
它。问题是我什至无法从 STD_OUTPUT_HANDLE
获得有效的 ConsoleScreenBufferInfoEx
。
下面的代码抛出此错误消息:
System.ArgumentException: 'Value does not fall within the expected range.'
句柄有效,但我收到此错误。我已经对每种数据类型和相关的 pinvoke 条目进行了四重检查——一切对我来说都很好。 GetConsoleScreenBufferInfoEx
没有 示例代码 ,我还没有找到可行的解决方案。
我的消息来源:
- pinvoke: ConsoleFunctions (kernel32)
- msdocs: CONSOLE_SCREEN_BUFFER_INFOEX structure
- msdocs: COLORREF
示例应用程序 (.NET Core 3.1):
要使此代码正常工作,项目的构建属性必须允许不安全代码。
[属性 -> 构建 -> 允许不安全代码]
using Microsoft.Win32.SafeHandles;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace ScreenBufferInfoExample
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern unsafe bool GetConsoleScreenBufferInfoEx(SafeFileHandle hConsoleOutput,
out CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo);
static void Main()
{
SafeFileHandle stdOut = GetStdHandle(-11);
if(stdOut.IsInvalid)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
CONSOLE_SCREEN_BUFFER_INFO_EX info = new CONSOLE_SCREEN_BUFFER_INFO_EX();
info.cbSize = (uint)Marshal.SizeOf(info);
if(!GetConsoleScreenBufferInfoEx(stdOut, out info)) {
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());// <- this gets thrown
// System.ArgumentException: 'Value does not fall within the expected range.'
}
Console.ReadKey(true);
}
}
[StructLayout(LayoutKind.Sequential)]
struct CONSOLE_SCREEN_BUFFER_INFO_EX
{
public uint cbSize;
public COORD dwSize;
public COORD dwCursorPosition;
public ushort wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
public ushort wPopupAttributes;
public bool bFullscreenSupported;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public COLORREF[] ColorTable;
}
[StructLayout(LayoutKind.Sequential)]
struct COORD
{
public short X;
public short Y;
}
[StructLayout(LayoutKind.Sequential)]
struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
struct COLORREF
{
public uint ColorDWORD;
public COLORREF(int r, int g, int b)
: this(Color.FromArgb(r, g, b)) { }
public COLORREF(Color color)
{
ColorDWORD = (uint)color.R
+ (((uint)color.G) << 8)
+ (((uint)color.B) << 16);
}
public Color GetColor()
{
return Color.FromArgb((int)(0x000000FFU & ColorDWORD),
(int)(0x0000FF00U & ColorDWORD) >> 8,
(int)(0x00FF0000U & ColorDWORD) >> 16);
}
public void SetColor(Color color)
{
ColorDWORD = (uint)color.R
+ (((uint)color.G) << 8)
+ (((uint)color.B) << 16);
}
}
}
pinvoke.net 经常有用,但并不总是正确的。
由于GetConsoleScreenBufferInfoEx方法需要传入传出信息,参数不能为out
,需要为ref
.
所以正确的声明是
[DllImport("kernel32.dll", SetLastError = true)]
public static extern unsafe bool GetConsoleScreenBufferInfoEx(SafeFileHandle hConsoleOutput,
ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo);
称为GetConsoleScreenBufferInfoEx(stdOut, ref info)
。
(我刚刚相应地更正了 pinvoke.net 上的页面)
GetConsoleScreenBufferInfoEx 无效 return 值
我正在尝试更改控制台的调色板。为了完成这项工作,我首先需要 Get
我的 ConsoleScreenBufferInfoEx
然后 Set
它。问题是我什至无法从 STD_OUTPUT_HANDLE
获得有效的 ConsoleScreenBufferInfoEx
。
下面的代码抛出此错误消息:
System.ArgumentException: 'Value does not fall within the expected range.'
句柄有效,但我收到此错误。我已经对每种数据类型和相关的 pinvoke 条目进行了四重检查——一切对我来说都很好。 GetConsoleScreenBufferInfoEx
没有 示例代码 ,我还没有找到可行的解决方案。
我的消息来源:
- pinvoke: ConsoleFunctions (kernel32)
- msdocs: CONSOLE_SCREEN_BUFFER_INFOEX structure
- msdocs: COLORREF
示例应用程序 (.NET Core 3.1):
要使此代码正常工作,项目的构建属性必须允许不安全代码。
[属性 -> 构建 -> 允许不安全代码]
using Microsoft.Win32.SafeHandles;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace ScreenBufferInfoExample
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern unsafe bool GetConsoleScreenBufferInfoEx(SafeFileHandle hConsoleOutput,
out CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo);
static void Main()
{
SafeFileHandle stdOut = GetStdHandle(-11);
if(stdOut.IsInvalid)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
CONSOLE_SCREEN_BUFFER_INFO_EX info = new CONSOLE_SCREEN_BUFFER_INFO_EX();
info.cbSize = (uint)Marshal.SizeOf(info);
if(!GetConsoleScreenBufferInfoEx(stdOut, out info)) {
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());// <- this gets thrown
// System.ArgumentException: 'Value does not fall within the expected range.'
}
Console.ReadKey(true);
}
}
[StructLayout(LayoutKind.Sequential)]
struct CONSOLE_SCREEN_BUFFER_INFO_EX
{
public uint cbSize;
public COORD dwSize;
public COORD dwCursorPosition;
public ushort wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
public ushort wPopupAttributes;
public bool bFullscreenSupported;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public COLORREF[] ColorTable;
}
[StructLayout(LayoutKind.Sequential)]
struct COORD
{
public short X;
public short Y;
}
[StructLayout(LayoutKind.Sequential)]
struct SMALL_RECT
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
struct COLORREF
{
public uint ColorDWORD;
public COLORREF(int r, int g, int b)
: this(Color.FromArgb(r, g, b)) { }
public COLORREF(Color color)
{
ColorDWORD = (uint)color.R
+ (((uint)color.G) << 8)
+ (((uint)color.B) << 16);
}
public Color GetColor()
{
return Color.FromArgb((int)(0x000000FFU & ColorDWORD),
(int)(0x0000FF00U & ColorDWORD) >> 8,
(int)(0x00FF0000U & ColorDWORD) >> 16);
}
public void SetColor(Color color)
{
ColorDWORD = (uint)color.R
+ (((uint)color.G) << 8)
+ (((uint)color.B) << 16);
}
}
}
pinvoke.net 经常有用,但并不总是正确的。
由于GetConsoleScreenBufferInfoEx方法需要传入传出信息,参数不能为out
,需要为ref
.
所以正确的声明是
[DllImport("kernel32.dll", SetLastError = true)]
public static extern unsafe bool GetConsoleScreenBufferInfoEx(SafeFileHandle hConsoleOutput,
ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo);
称为GetConsoleScreenBufferInfoEx(stdOut, ref info)
。
(我刚刚相应地更正了 pinvoke.net 上的页面)