无法更改打印机的DEVMODE [英] Can't change DEVMODE of a printer
问题描述
我需要为当前的打印任务更改打印机的DEVMODE
,以通过标准和特定于设备的设置.我执行以下操作:
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();
}
当我尝试使用NullReferenceException
执行PrinterSettings.SetHdevmode
并且没有任何有意义的错误信息时,它将失败. d.PrinterSettings
不为null,在PrinterSettings.SetHdevmode
方法内部引发异常.
所以我的问题是:怎么了? byte[]
到IntPtr
投放错误吗?也许SetHdevmode
期望的不是byte[]
数组?
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?
我从注册表中获得了byte[] devmode_data
数组.这是一个有效值,并且与当前打印机设置中使用的值相同.
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.
推荐答案
SetHdevmode
需要HGLOBAL
.您可以通过Marshal.AllocHGlobal
从.Net获取HGLOBAL
.然后,您可以使用Marshal.Copy(byte[], int, IntPtr, int)
从托管字节数组复制到HGLOBAL
.见下文:
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);
字节数组可以部分地作为结构来处理,但这需要 p/调用定义.但是,PrinterSettings
类将不接受结构,因此在这种情况下将不需要这样做.另外,DEVMODE
结构的长度可变,以允许打印机驱动程序添加其他不透明数据,因此转换时不会丢失数据.
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.
请参见如何保存和恢复`PrinterSettings`?更多.
这篇关于无法更改打印机的DEVMODE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!