无法更改打印机的 DEVMODE

发布于 2024-12-17 22:51:37 字数 1006 浏览 7 评论 0原文

我需要更改当前打印任务的打印机的 DEVMODE 以通过标准和设备特定的设置。我执行以下操作:

PrintDocument d = new PrintDocument();
d.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"; // example printer name           
byte[] devmode_data; // contains a valid value that is obtained from registry
IntPtr devmode = IntPtr.Zero;
GCHandle handle = GCHandle.Alloc(devmode_data, GCHandleType.Pinned);
try
{
    devmode = handle.AddrOfPinnedObject();
    if (devmode != IntPtr.Zero) d.PrinterSettings.SetHdevmode(devmode);
}
finally
{
    if (handle.IsAllocated) handle.Free();
}

当我尝试使用 NullReferenceException 执行 PrinterSettings.SetHdevmode 且没有任何有意义的错误信息时,它会失败。 d.PrinterSettings 不为 null,异常在 PrinterSettings.SetHdevmode 方法内部抛出。
所以我的问题是:出了什么问题? byte[]IntPtr 的转换是否错误?也许 SetHdevmode 需要 byte[] 数组以外的东西?

我从注册表中获取了 byte[] devmode_data 数组。它是一个有效值,并且与当前打印机设置中使用的值相同。

I need to change DEVMODE of printer for current printing task to pass standard and device-specific settings. I do the following:

PrintDocument d = new PrintDocument();
d.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"; // example printer name           
byte[] devmode_data; // contains a valid value that is obtained from registry
IntPtr devmode = IntPtr.Zero;
GCHandle handle = GCHandle.Alloc(devmode_data, GCHandleType.Pinned);
try
{
    devmode = handle.AddrOfPinnedObject();
    if (devmode != IntPtr.Zero) d.PrinterSettings.SetHdevmode(devmode);
}
finally
{
    if (handle.IsAllocated) handle.Free();
}

It fails when I attempt to execute PrinterSettings.SetHdevmode with a NullReferenceException and without any meaningful error info. d.PrinterSettings is not null, the exception is thrown inside of PrinterSettings.SetHdevmode method.
So my question is: what is wrong? Is the byte[] to IntPtr cast wrong? Maybe SetHdevmode expects something other than a byte[] array?

I get the byte[] devmode_data array from the registry. It is a valid value and it is same value that is used in current printer settings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹂绝世的画 2024-12-24 22:51:37

我按以下方式修改了您的代码,因为我没有 devmode_data 的任何有效数据:

devmode = d.PrinterSettings.GetHdevmode();
if (devmode != IntPtr.Zero) d.PrinterSettings.SetHdevmode(devmode);

现在这里也不例外。

请向我提供您的 devmode_data 数据,或者检查您自己的数据是否有效!

I modified your code in the following way, since I don't have any valid data for devmode_data:

devmode = d.PrinterSettings.GetHdevmode();
if (devmode != IntPtr.Zero) d.PrinterSettings.SetHdevmode(devmode);

and now there is no exception here.

Please, provide me with your data for devmode_data or check for your own, if it is valid or not!

不羁少年 2024-12-24 22:51:37

SetHdevmode 需要一个 HGLOBAL。您可以通过 Marshal.AllocHGlobal 从 .Net 获取 HGLOBAL。然后,您可以使用 Marshal.Copy(byte[], int, IntPtr, int) 将托管字节数组复制到 HGLOBAL。见下文:

var pDevMode = Marshal.AllocHGlobal(devmode_data.Length);
Marshal.Copy(devmode_data, 0, pDevMode, devmode_data.Length);

d.PrinterSettings.SetHdevmode(pDevMode);
Marshal.FreeHGlobal(pDevMode);

字节数组可以部分作为结构处理,但这需要 p/调用定义。然而,PrinterSettings 类不接受结构,因此在这种情况下不需要这样做。此外,DEVMODE 结构是可变长度的,以允许打印机驱动程序添加额外的不透明数据,因此不可能在不丢失数据的情况下进行转换。

有关详细信息,请参阅如何保存和恢复“PrinterSettings”?

SetHdevmode expects an HGLOBAL. You can get an HGLOBAL from .Net via Marshal.AllocHGlobal. Then, you can use Marshal.Copy(byte[], int, IntPtr, int) to copy from your managed byte array to the HGLOBAL. See below:

var pDevMode = Marshal.AllocHGlobal(devmode_data.Length);
Marshal.Copy(devmode_data, 0, pDevMode, devmode_data.Length);

d.PrinterSettings.SetHdevmode(pDevMode);
Marshal.FreeHGlobal(pDevMode);

The byte array can be partially handled as a structure, but that will require p/Invoke definitions. The PrinterSettings class, however, will not accept a structure, so doing so would be unneeded in this case. Additionally, the DEVMODE structure is variable length to allow for printer drivers to add additional opaque data, so it would not be possible to convert without data loss.

See How can I save and restore `PrinterSettings`? for more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文