gpt4 book ai didi

c# - 如何保存和恢复 `PrinterSettings` ?

转载 作者:行者123 更新时间:2023-11-30 14:54:01 28 4
gpt4 key购买 nike

我有一个应用程序要保存 PrinterSettings用户选择注册表,然后在我们准备好打印时恢复它们。有没有办法序列化 PrinterSettings

最佳答案

整个PrinterSettings——包括供应商特定的选项——可以通过保存通过PrinterSettings.GetHdevmode()接收的HDEVMODE结构来存储,然后通过 PrinterSettings.SetHdevmode(IntPtr) 恢复。

下面的类将添加两个扩展方法,以将 PrinterSettings 保存到 byte 数组,以及从中恢复。

警告程序员:一些打印机驱动程序不具有向后或向前兼容性,并且如果使用来自另一个版本或架构的驱动程序的持久数据可能会崩溃。

使用示例:

PrinterSettings CurrentSettings;
const string myAppKeyName = @"Software\MyApplicationName";
const string printerSettingValueName = "PrinterSettings"

// save
using (var sk = Registry.CurrentUser.CreateSubKey(myAppKeyName))
{
sk.SetValue(printerSettingValueName, this.CurrentSettings.GetDevModeData(), RegistryValueKind.Binary);
}

// restore
using (var sk = Registry.CurrentUser.CreateSubKey(myAppKeyName))
{
var data = sk.GetValue(printerSettingValueName, RegistryValueKind.Binary) as byte[];

this.CurrentSettings = new PrinterSettings();
if (data != null)
{
this.CurrentSettings.SetDevModeData(data);
}
}

实现:

static class PrinterSettingsExtensions
{
public static byte[] GetDevModeData(this PrinterSettings settings)
{
//Contract.Requires(settings != null);

byte[] devModeData;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// cer since hDevMode is not a SafeHandle
}
finally
{
var hDevMode = settings.GetHdevmode();
try
{
IntPtr pDevMode = NativeMethods.GlobalLock(hDevMode);
try
{
var devMode = (NativeMethods.DEVMODE)Marshal.PtrToStructure(
pDevMode, typeof(NativeMethods.DEVMODE));

var devModeSize = devMode.dmSize + devMode.dmDriverExtra;
devModeData = new byte[devModeSize];
Marshal.Copy(pDevMode, devModeData, 0, devModeSize);
}
finally
{
NativeMethods.GlobalUnlock(hDevMode);
}
}
finally
{
Marshal.FreeHGlobal(hDevMode);
}
}
return devModeData;
}

public static void SetDevModeData(this PrinterSettings settings, byte[] data)
{
//Contract.Requires(settings != null);
//Contract.Requires(data != null);
//Contract.Requires(data.Length >= Marshal.SizeOf(typeof(NativeMethods.DEVMODE)));

RuntimeHelpers.PrepareConstrainedRegions();
try
{
// cer since AllocHGlobal does not return SafeHandle
}
finally
{
var pDevMode = Marshal.AllocHGlobal(data.Length);
try
{
// we don't have to worry about GlobalLock since AllocHGlobal only uses LMEM_FIXED
Marshal.Copy(data, 0, pDevMode, data.Length);
var devMode = (NativeMethods.DEVMODE)Marshal.PtrToStructure(
pDevMode, typeof(NativeMethods.DEVMODE));

// The printer name must match the original printer, otherwise an AV will be thrown
settings.PrinterName = devMode.dmDeviceName;

// SetHDevmode creates a copy of the devmode, so we don't have to keep ours around
settings.SetHdevmode(pDevMode);
}
finally
{
Marshal.FreeHGlobal(pDevMode);
}
}
}
}

static class NativeMethods
{
private const string Kernel32 = "kernel32.dll";

[DllImport(Kernel32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GlobalLock(IntPtr handle);

[DllImport(Kernel32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool GlobalUnlock(IntPtr handle);

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Auto)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 32;
private const int CCHFORMNAME = 32;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;

public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;

public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
}

相关:

关于c# - 如何保存和恢复 `PrinterSettings` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28007554/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com