分类目录归档:C#

打印队列监控(拦截+取消+状态获取)(附C#,C++,VB实现)

Print Spooler API

https://docs.microsoft.com/zh-cn/windows/win32/printdocs/print-spooler-api

The Print Spooler API provides an interface to the print spooler for applications to manage printers and print jobs.

The Print Spooler API is used by an application as part of its programming and not directly by end users.

PrintQueue.GetPrintJobInfoCollection Method

Creates a collection that contains a PrintSystemJobInfo object for each job in the queue.

https://docs.microsoft.com/en-us/dotnet/api/system.printing.printqueue.getprintjobinfocollection?view=netframework-4.8

"Virtual Printer" or "Moving Printjobs" (C++)

https://cboard.cprogramming.com/windows-programming/108156-virtual-printer-moving-printjobs.html

Monitor jobs in a printer queue (C# .NET)

https://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET

Monitoring a Printer Queue from VB.NET

https://www.codeproject.com/Articles/3313/Monitoring-a-Printer-Queue-from-VB-NET

C#实现自动打印PDF

采用PDFRender4NET

//打印机设置
PrinterSettings settings = new PrinterSettings();
settings.PrinterName = printername;
settings.PrintToFile = false;
settings.Copies = 1;
settings.PrintRange = PrintRange.AllPages;
//设置纸张大小(可以不设置取,取默认设置)
PaperSize ps = new PaperSize("Your Paper Name",595,842);
ps.RawKind = 9; //如果是自定义纸张,就要大于118

//打印设置
PDFRender.Printing.PDFPrintSettings pdfPrintSettings = new PDFRender.Printing.PDFPrintSettings(settings);
pdfPrintSettings.AutoRotate = false;            //自动旋转
pdfPrintSettings.BitmapPrintResolution = 560;   //图片打印精度                    
pdfPrintSettings.PaperSize = ps;                //纸张尺寸
pdfPrintSettings.PageScaling = PDFRender.Printing.PageScaling.FitToPrinterMarginsProportional;

pdfFile.Print(pdfPrintSettings);

代码详见: https://github.com/HiRaygo/DocumentPrint/blob/master/PdfPrint.cs

采用SumatraPDF或Acrobat Reader方案

 public static PrintEngine SumatraPDF = new PrintEngine("Sumatra PDF Reader",
            ((printerName, filePath, documentName) => 
            {
                string app = Path.Combine(Program.localPath, "SumatraPDF.exe");
                string args = string.Format("-silent -exit-on-print -print-to \"{0}\" \"{1}\"", printerName, filePath);

                Process p = new Process();
                p.StartInfo = new ProcessStartInfo()
                {
                    CreateNoWindow = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    FileName = app,
                    Arguments = args
                };
                //if (User.isNetworkService())
                //{
                //    p.StartInfo.UserName = Program.config.serviceLogin;
                //    p.StartInfo.Password = tools.secureString(tools.Decrypt(Program.config.servicePass));
                //    p.StartInfo.Domain = Program.config.serviceDomain;
                //    p.StartInfo.LoadUserProfile = true;
                //    p.StartInfo.UseShellExecute = false;
                //}
                p.Start();

            })){};

        /// <summary>
        /// Print via external programm Acrobat Reader
        /// </summary>
        public static PrintEngine AcrobatReader = new PrintEngine("Acrobat Reader",
            ((printerName, filePath, documentName) =>
            {                
                string app = Registry.LocalMachine.OpenSubKey(
                        @"SOFTWARE\Microsoft\Windows\CurrentVersion" +
                        @"\App Paths\AcroRd32.exe"
                    ).GetValue("").ToString()
                ;
                string args = string.Format("/h /t \"{0}\" \"{1}\"", filePath, printerName);

                Process p = new Process();
                p.StartInfo = new ProcessStartInfo()
                {
                    CreateNoWindow = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    FileName = app,
                    Arguments = args
                };
                //if (User.isNetworkService())
                //{

                //    p.StartInfo.UserName = Program.config.serviceLogin;
                //    p.StartInfo.Password = tools.secureString(tools.Decrypt(Program.config.servicePass));
                //    p.StartInfo.Domain = Program.config.serviceDomain;
                //    p.StartInfo.LoadUserProfile = true;
                //    p.StartInfo.UseShellExecute = false;
                //}
                p.Start();

})){};

代码详见: https://github.com/RepairShopr/AutoPrintr-win/blob/master/AutoPrintr/modules/PrintEngines.cs

Windows监控打印机任务实现付费打印

如何拦截打印任务

参考:

  • Intercept any print job and prompt for password.

    FindFirstPrinterChangeNotification()
    FindNextPrinterChangeNotification()
    if pdwChange = PRINTER_CHANGE_ADD_JOB you get the Job ID from PRINTER_NOTIFY_INFO_DATA
    You pause the Job with
    SetJob() and JOB_CONTROL_PAUSE
    You call your Dialog Box, then

    you resume the Job with
    SetJob() and JOB_CONTROL_RESUME
    or you cancel it with
    SetJob() and JOB_CONTROL_DELETE

  • Monitor jobs in a printer queue (.NET)

    There is a lot of code available in the internet (CodeProject as well as other sites) about the API calls to do print spool monitoring. However, I was not able to find any code that would help the user to enable monitoring one or more print queues with minimal code changes. So, I created a class (PrintQueueMonitor) that would allow the user to monitor the print queue for job changes and raise an event as and when jobs get added to the queue or job status gets changed in the queue.

C#编写的可供PHP调用的com dll(Visual studio 2017)

新增类库项目

依次选择“文件”》“新建”》“项目”,然后选择“类库(.net framework)”

添加引用

在“解决方案资源管理器”的“引用”点击鼠标右键,才程序集中搜索“InteropServices”,勾选“System.Runtime.InteropServices”

com可见

在“解决方案资源管理器”的项目名称上点击鼠标右键,选择“属性”,然后在“应用程序”面板选择“程序集信息”,勾选“使程序集COM可见”

签名

在“解决方案资源管理器”的项目名称上点击鼠标右键,选择“属性”,然后在“签名”面板勾选“为程序集签名”,然后在下拉菜单选择“新建”,输入“签名文件名称”,取消“使用密码保护密钥文件”勾选,点击确认

创建程序

using System.Runtime.InteropServices;

namespace HelloWorld
{ 
    [ComVisible(true)]
    public class Say
    {
        public string Hello()
        {
            return "Hello World";
        }
    }
}

发布dll

点击主菜单“生成”》“生成解决方案”(或者按F6)

注册com

按键盘上的win键,打开开始菜单,输入"vs"搜索,鼠标右键点击"VS 2017开发人员命令提示符",选择用管理员身份打开;

进入生成的dll目录(通常在项目的bin/release目录下)

cd d:/helloworld/bin/release
regasm HelloWord.dll
gacutil /i HelloWord.dll

PHP调用com

<?php  
$r=new Com("HelloWorld.Say");  
$s=$r->Hello();  
echo $s;

调用出现Uncaught com_exception: Failed to create COM object

http://www.drupalonwindows.com/en/blog/calling-net-framework-and-net-assemblies-php

backgroundWorker in c# console application

A sample console program with backgroundworkwr.

class Program
{
    private static BackgroundWorker worker = new BackgroundWorker();
    private event EventHandler BackgroundWorkFinished;

    static void Main(string[] args)
    {
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;

        Console.WriteLine("Starting Application...");

        worker.RunWorkerAsync();
        Console.ReadKey();
    }

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine(e.ProgressPercentage.ToString());
    }

    static void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        Console.WriteLine("Starting to do some work now...");
        int i;
        for (i = 1; i < 10; i++)
        {
            Thread.Sleep(1000);
            worker.ReportProgress(Convert.ToInt32((100.0 * i) / 10));
        }

        e.Result = i;
    }

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine("Value Of i = " + e.Result.ToString());
        Console.WriteLine("Done now...");
    }
}