背景:
我正在使用.NET 4.0在C#中编写应用程序.它按特定顺序打印一堆文档.这些文档具有所有不同的类型,实际上是使用带有"print"动词的ShellExecute打印的.
为了确保订单不会混乱,我想检查所涉及的打印机的打印队列.我的主循环看起来像:
如何使用托管代码监控打印队列?
我找到了一些使用非托管调用做类似事情的好例子(例如:http://blogs.msdn.com/b/martijnh/archive/2009/08/05/printmonitor-ac-print-spooler-monitor.aspx).另外,我知道如何查看c:\ windows\system32\spool下的假脱机文件...并以这种方式解决问题.
但是,这些解决方案都不是非常令人满意......我正在调用非托管鳕鱼的数量,我觉得我应该用C++编写应用程序.(并没有.NET依赖/开销.)
主要问题:是否真的无法仅使用托管呼叫监控打印队列?
更一般的问题:我来自java世界,当我想做一些特定于操作系统的东西或者需要与MS世界中的其他东西进行交互时,通常只使用.NET语言.(例如SSIS组件.)
似乎每次我开始一个项目时我都会遇到同样的混乱:对本机函数,COM东西等的各种调用等.
次要问题:我对.NET哲学或实现缺少什么?(我是不是觉得托管库做得不够好?对于任何需要执行Windows特定操作的东西,例如操纵打印队列 ,.NET是不是错误的选择?)我得到(或者认为我得到).NET是从理论上讲,它应该与操作系统无关.但是大多数现代操作系统肯定都有打印机和打印队列等等.(所以如果你有做这些事情的泛型调用,它们可以在每个平台的框架版本上实现..)
我正在更新我们的"打印机监控"应用程序.以前,此应用程序在Windows 2000服务器上成功运行.现在我们转移到Windows 7服务器.在Windows 7上,我们的"打印监视器"应用程序崩溃了.当我调试它时,我发现我们的SetJob函数抛出以下异常:
参数不正确.
有人对这个有了解吗?
功能调用:
SetJob(
mhPrinter,
midJob,
0,
IntPtr.Zero,
PrintJobControlCommands.JOB_CONTROL_PAUSE) 'Here exception is thrown
Run Code Online (Sandbox Code Playgroud)
我们使用的后台处理程序API:
<DllImport("winspool.drv", EntryPoint:="SetJob", _
SetLastError:=True, CharSet:=CharSet.Ansi, _
ExactSpelling:=False, _
CallingConvention:=CallingConvention.StdCall)> _
Public Function SetJob _
(<InAttribute()> ByVal hPrinter As IntPtr, _
<InAttribute()> ByVal dwJobId As Int32, _
<InAttribute()> ByVal Level As Int32, _
<InAttribute()> ByVal lpJob As IntPtr, _
<InAttribute(), MarshalAs(UnmanagedType.U4)> ByVal dwCommand As PrintJobControlCommands _
) As Boolean
Run Code Online (Sandbox Code Playgroud) 我正在测试将作业发送到打印机队列的软件,然后在成功打印时上升标志.它还需要检测失败作业中正确打印的页数.
虽然有很多"虚拟打印机",但它们都完美地处理了他们的工作......这就是问题所在.
是否有打印机模拟器可以控制它发送回窗口假脱机程序的信号,如打印页面,纸张错误,卡纸等?
我对打印机驱动程序处理打印机的原始输出不感兴趣,而是驱动程序传回窗口假脱机程序的信号.
有没有一种方法可以通过编程方式配置打印到文件(本地文件端口)的打印机以绕过后台打印程序服务,并将数据直接发送到文件?
我看过@ prnadmin.dll(那里没有相关内容)和WMI(没有任何相关内容)。有任何想法吗 ?不,我不想停止Windows(XP SP3)中的后台打印程序服务,只是让打印机绕过它即可。
有没有办法重新打印假脱机文件?
如果有办法,我找不到任何例子或文章.
编辑:当我说再版时,我的意思是同一台打印机