You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位下C#自定义纸张尺寸打印正常,64位异常求助

64位环境下C#设置自定义打印纸张尺寸无效的解决方法

问题背景

需求:打印指定尺寸图片,打印机自动裁切纸张。
异常表现:32位环境下代码打印正常,但64位环境中,代码设置的纸张尺寸看似正确,打印机却按默认纸张尺寸裁切。手动在Windows设置中修改打印机纸张尺寸后,打印恢复正常,推测64位环境下C#代码无法正确修改该设置。

用户提供的原代码:

var pd = new PrintDocument();
pd.PrintPage += PrintThreeImagesPage;
PrinterSettings printerSettings = new PrinterSettings();
printerSettings.PrinterName = "IP60 Photo";

pd.PrinterSettings = printerSettings;
pd.DefaultPageSettings.PaperSize = GetCustomPaperSize(printerSettings, 608, 258);
pd.Print();

private static PaperSize? GetCustomPaperSize(PrinterSettings printerSettings, int width, int height)
{
    PaperSize? paperSize = null;

    foreach (PaperSize size in printerSettings.PaperSizes)
    {
        if (size.Width == width && size.Height == height)
        {
            paperSize = size;
            break;
        }
    }

    if (paperSize == null)
    {
        // If the custom paper size doesn't exist, create a new one
        Type type = typeof(PaperSize);
        paperSize = (PaperSize)type.InvokeMember("Custom",
            System.Reflection.BindingFlags.CreateInstance |
            System.Reflection.BindingFlags.Public |
            System.Reflection.BindingFlags.Instance |
            System.Reflection.BindingFlags.NonPublic,
            null, printerSettings, new object[] { "Custom", width, height });
    }

    return paperSize;
}

解决方法

1. 改用独立的PageSettings对象

64位环境下,直接修改PrintDocument.DefaultPageSettings可能无法正确将参数传递给打印机驱动,建议单独创建PageSettings并绑定:

var pd = new PrintDocument();
pd.PrintPage += PrintThreeImagesPage;
var printerSettings = new PrinterSettings { PrinterName = "IP60 Photo" };

// 创建独立的PageSettings实例
var pageSettings = new PageSettings(printerSettings);
pageSettings.PaperSize = GetCustomPaperSize(printerSettings, 608, 258);

// 替换DefaultPageSettings
pd.DefaultPageSettings = pageSettings;
pd.Print();

2. 替换反射创建自定义PaperSize的逻辑

原代码使用反射调用非公开构造函数,64位环境下兼容性差,改用PaperSize的公开API创建自定义尺寸:

private static PaperSize GetCustomPaperSize(PrinterSettings printerSettings, int width, int height)
{
    // 优先查找已存在的自定义尺寸
    foreach (PaperSize size in printerSettings.PaperSizes)
    {
        if (size.PaperKind == PaperKind.Custom && size.Width == width && size.Height == height)
        {
            return size;
        }
    }

    // 用公开构造函数创建自定义尺寸
    var customSize = new PaperSize("Custom", width, height);
    // 将尺寸添加到打印机支持列表(部分驱动要求)
    printerSettings.PaperSizes.Add(customSize);
    return customSize;
}

3. 检查并更新64位打印机驱动

很多老打印机的32位驱动和64位驱动行为差异大,确认安装官方发布的64位驱动,避免使用兼容模式的32位驱动。部分64位驱动会忽略代码传递的自定义尺寸,仅读取系统预设值。

4. 强制锁定打印区域

在PrintPage事件中手动设置打印区域,确保输出匹配自定义纸张尺寸:

private void PrintThreeImagesPage(object sender, PrintPageEventArgs e)
{
    var paperSize = e.PageSettings.PaperSize;
    // 取消边距限制
    e.PageSettings.Margins = new Margins(0, 0, 0, 0);
    // 设置打印裁剪区域为整个纸张
    e.Graphics.SetClip(new RectangleF(0, 0, paperSize.Width, paperSize.Height));
    
    // 此处添加你的图片绘制逻辑
}

5. 通过Windows API修改打印机默认尺寸(需管理员权限)

如果以上方法都无效,可以调用Win32 API直接修改打印机的系统默认纸张尺寸,实现持久化设置:

// 引入Win32 API
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);

// 具体实现需结合PRINTER_INFO_9等结构体,可参考Windows SDK文档
// 注意:此操作需要管理员权限,适合需要固定默认纸张尺寸的场景

内容的提问来源于stack exchange,提问作者JoachimVeulemans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:45:01