如何使用C#为虚拟打印机自动化安装XPS类打印机驱动
问题
如何使用C#实现打印机驱动安装向导的自动化操作,为虚拟打印机安装“XPS Class Printer Driver”?

我已经开发完对应安装程序,实现了虚拟打印机和对应端口的创建,但现在需要用到本机没预装的Microsoft XPS Printer Driver。我可以通过上面截图里的打印机驱动向导手动装完这个驱动,但一直没找到用C#把这个流程自动化的可行方法。
我知道可以调用DRIVER_INFO_6结构体或者Management API做相关操作,但不清楚具体实现步骤。
实现方案
根本不需要模拟向导点击操作,直接调用Windows打印后台处理程序(Win32 Spooler API),指定系统内置的XPS驱动inf路径就能完成安装,比UI模拟稳定得多,不受系统版本、弹窗层级影响。
核心逻辑
- 微软内置的XPS类驱动默认存放在系统驱动存储里,inf固定路径是
C:\Windows\INF\ntprint.inf,驱动自带微软签名,不需要额外下载安装包 - 调用
AddPrinterDriverEx函数,传入填充正确的DRIVER_INFO_6结构体就能完成驱动安装,完全跳过手动向导的点选步骤 - 驱动装完直接绑定到你已经创建好的虚拟打印机端口就行,不用走系统的添加设备向导
具体实现代码
1. 定义Win32 API和对应结构体
注意区分32位和64位系统的环境适配:
using System; using System.IO; using System.Runtime.InteropServices; public static class SpoolerApi { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DRIVER_INFO_6 { public uint cVersion; [MarshalAs(UnmanagedType.LPTStr)] public string pName; [MarshalAs(UnmanagedType.LPTStr)] public string pEnvironment; [MarshalAs(UnmanagedType.LPTStr)] public string pDriverPath; [MarshalAs(UnmanagedType.LPTStr)] public string pDataFile; [MarshalAs(UnmanagedType.LPTStr)] public string pConfigFile; [MarshalAs(UnmanagedType.LPTStr)] public string pHelpFile; [MarshalAs(UnmanagedType.LPTStr)] public string pDependentFiles; [MarshalAs(UnmanagedType.LPTStr)] public string pMonitorName; [MarshalAs(UnmanagedType.LPTStr)] public string pDefaultDataType; [MarshalAs(UnmanagedType.LPTStr)] public string pszzPreviousNames; public System.Runtime.InteropServices.ComTypes.FILETIME ftDriverDate; public ulong dwlDriverVersion; [MarshalAs(UnmanagedType.LPTStr)] public string pszMfgName; [MarshalAs(UnmanagedType.LPTStr)] public string pszOEMUrl; [MarshalAs(UnmanagedType.LPTStr)] public string pszHardwareID; [MarshalAs(UnmanagedType.LPTStr)] public string pszProvider; [MarshalAs(UnmanagedType.LPTStr)] public string pszPrintProcessor; [MarshalAs(UnmanagedType.LPTStr)] public string pszVendorSetup; [MarshalAs(UnmanagedType.LPTStr)] public string pszzColorProfiles; [MarshalAs(UnmanagedType.LPTStr)] public string pszInfPath; public uint dwPrinterDriverAttributes; [MarshalAs(UnmanagedType.LPTStr)] public string pszzCoreDriverDependencies; public System.Runtime.InteropServices.ComTypes.FILETIME ftMinInboxDriverVerDate; public ulong dwlMinInboxDriverVerVersion; } [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool AddPrinterDriverEx( string pName, uint Level, ref DRIVER_INFO_6 pDriverInfo, uint dwFileCopyFlags); public const uint APD_COPY_ALL_FILES = 0x00000004; public const uint APD_COPY_FROM_DIRECTORY = 0x00000010; public const uint APD_INSTALL_WARNED_DRIVER = 0x00008000; }
2. 填充驱动参数执行安装
XPS Class Driver的参数都是系统内置固定值,不需要手动选制造商、型号,直接按下面的值填充就行:
public static bool InstallXpsClassDriver() { // 适配系统架构,对应驱动存放路径 string env = Environment.Is64BitOperatingSystem ? "Windows x64" : "Windows NT x86"; string driverDir = Environment.Is64BitOperatingSystem ? @"C:\Windows\System32\spool\drivers\x64\3" : @"C:\Windows\System32\spool\drivers\W32X86\3"; var driverInfo = new SpoolerApi.DRIVER_INFO_6 { cVersion = 3, pName = "Microsoft XPS Class Driver", pEnvironment = env, pDriverPath = Path.Combine(driverDir, "mxdwdrv.dll"), pConfigFile = Path.Combine(driverDir, "unidrvui.dll"), pDataFile = Path.Combine(driverDir, "xpssvcs.dll"), pszInfPath = @"C:\Windows\INF\ntprint.inf", pszMfgName = "Microsoft", pszHardwareID = "Microsoft_XPS_Class_Driver", pszProvider = "Microsoft", pszPrintProcessor = "winprint", pDefaultDataType = "RAW" }; bool installResult = SpoolerApi.AddPrinterDriverEx( null, // 本地机器直接传null 6, // 对应DRIVER_INFO_6结构体级别 ref driverInfo, SpoolerApi.APD_COPY_ALL_FILES | SpoolerApi.APD_COPY_FROM_DIRECTORY | SpoolerApi.APD_INSTALL_WARNED_DRIVER ); if (!installResult) { int errCode = Marshal.GetLastWin32Error(); // 错误码0、1795都代表驱动已经存在,属于正常情况 if (errCode == 0 || errCode == 1795) return true; throw new InvalidOperationException($"驱动安装失败,系统错误码:{errCode}"); } return true; }
3. 绑定驱动到已创建的虚拟打印机
驱动安装完成后,调用AddPrinter或者SetPrinterAPI,把你之前创建的虚拟打印机的驱动名指定为Microsoft XPS Class Driver就完成全部流程了。
踩坑提醒
- 代码必须以管理员权限运行,安装打印机驱动是系统级操作,记得在程序manifest里配置
requireAdministrator权限级别 - 别折腾UI自动化、模拟键鼠点击那套,Win10、Win11、Server版的向导界面布局、控件ID都不一样,稳定性极差
- 不推荐用WMI/Management API装打印驱动,WMI对打印模块的封装有很多已知bug,64位系统下经常出权限不足、参数不识别的问题,直接调原生Spooler API是最靠谱的方案
- 如果是精简版系统删掉了内置ntprint.inf,这个方法会失败,这种情况提前从对应版本的系统镜像里提取内置驱动包,替换代码里的inf路径即可
内容的提问来源于stack exchange,提问作者Ashish Gehlot
相关产品推荐
相关产品推荐

