XPS Printing


1 129810
2 86534
3 69567
4 68592
5 67887
6 63032
7 63322
8 61738
9 65949
10 78690


自已整左個program仔去試concurreny send xps job..上面係不同concurrency的結果..
class XPSPrintTest
    {
        static Stopwatch completeStopWatch = new Stopwatch();
        static bool Done = false;
        static object jj = new object();
        static object intLock = new object();
        const int targetCounter = 100;
        static int _completeCounter = 0;
        static int CompleteCounter { get
            {
                lock(intLock)
                {
                    return _completeCounter;
                }
            }
            set
            { lock(intLock)
                {
                    _completeCounter = value;
                    if(_completeCounter == targetCounter)
                    {
                        completeStopWatch.Stop();
                        Done = true;
                        Console.WriteLine($"Completed {targetCounter} Jobs! Elapsed time: {completeStopWatch.ElapsedMilliseconds}");
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            completeStopWatch = new Stopwatch();
            completeStopWatch.Start();
            string xpsFilePath = "";
            string printerName = "";
           
           

        int concurrency = 1;
            if (args.Count() >0)
            {
                xpsFilePath = args[0];
                printerName = args[1];
                concurrency = int.Parse(args[2]);
            }
            else
            {
                xpsFilePath = @".\\TargetFile.xps";
                printerName = "_blackhole";
                concurrency = 1;
            }
            bool result = false;

            for (int i = 0; i < concurrency; i++)
            {
                var aa = i;
                Thread t = new Thread(() =>
                {

                    while (!Console.KeyAvailable&&!Done)
                    {
                        Stopwatch sw1 = new Stopwatch();
                        sw1.Start();
                        try
                        {
                            result = Print(xpsFilePath, printerName, new PrintTicket());
                            if(result == true)
                            {
                               // CompleteCounter++;
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                        }
                        sw1.Stop();
                     
                        Console.WriteLine($"{aa} {result} {sw1.ElapsedMilliseconds}");
                    }
                });
                t.Start();
            }
            Console.ReadLine();

        }

        /// <summary>
        /// Prints the specified XPS document to a printer using the native XPS Print API.
        /// </summary>
        /// <param name="xpsFilePath">The path to the XPS document.</param>
        /// <param name="printerName">The printer name.</param>
        /// <param name="printTicket">A PrintTicket with settings for this print job.</param>
        /// <returns><c>true</c> if the document was successfully printed; otherwise, <c>false</c>.</returns>
        /// <remarks>This method should be called from a background thread.</remarks>
        public static bool Print(string xpsFilePath, string printerName, PrintTicket printTicket)
        {

        //    lock (jj)
          //  {
                // try to create the XPS Object Model factory (only available on Windows 7 and Vista with the Platform Update)
                IXpsOMObjectFactory xpsFactory = null;
                try
                {
                    xpsFactory = (IXpsOMObjectFactory)new XpsOMObjectFactory();
                }
                catch (COMException)
                {
                    // OS doesn't support XPS Document API
                    return false;
                }

                bool success = false;
                IXpsOMPackage package = null;

                try
                {
                    // load the saved document as a native XpsOMPackage
                    package = xpsFactory.CreatePackageFromFile(xpsFilePath, false);

                    using (ManualResetEvent handle = new ManualResetEvent(false))
                    {
                        // attempt to start the print job
                        IXpsPrintJob printJob;
                        IXpsPrintJobStream docStream, ticketStream;
                    int hresult = NativeMethods.StartXpsPrintJob(printerName, "FUCK", null, IntPtr.Zero, handle.SafeWaitHandle, null, 0, out printJob, out docStream, out ticketStream);

                  //  IXpsOMPackageTarget target;
                   // int hresult = NativeMethods.StartXpsPrintJob1(printerName, "FUCK", null, IntPtr.Zero, handle.SafeWaitHandle, out printJob, out target);

                    // check for success (NOTE: checking HRESULT value directly instead of calling Marshal.ThrowExceptionForHR to avoid proliferation of 'catch' blocks)
                    if (hresult >= 0)
                        {
                            // write the current printer settings to the print ticket stream
                            byte[] ticketData = printTicket.GetXmlStream().ToArray();
                            uint bytesWritten;
                            ticketStream.Write(ticketData, (uint)ticketData.Length, out bytesWritten);
                            ticketStream.Close();

                            // write the XPS package to the document stream
                           package.WriteToStream(docStream, false);
                            docStream.Close();

                            // wait for printing to finish
                            handle.WaitOne();
                            success = true;
                            XPS_JOB_STATUS aa ;
                            printJob.GetJobStatus(out aa);
                        Console.WriteLine(aa.jobId);
                       
                        }
                    }
                }
                catch (COMException ex)
                {
                Console.WriteLine("***************************" + ex);
                }
                catch (DllNotFoundException ex)
                {
                    // OS doesn't support XPS Print API
                }
                catch (EntryPointNotFoundException)
                {
                    // OS doesn't support XPS Print API
                }
            catch (Exception ex)
            {
                Console.WriteLine("***************************" + ex);
            }
            // force the XPS package to be released, so that the temporary file can be deleted
            if (package != null)
                    Marshal.FinalReleaseComObject(package);

                return success;
         //   }
        }
    }
 internal static class NativeMethods
    {
        [DllImport("XpsPrint.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
        public static extern int StartXpsPrintJob(string printerName, string jobName, string outputFileName, IntPtr progressEvent, SafeWaitHandle completionEvent,
            [MarshalAs(UnmanagedType.LPArray)] byte[] printablePagesOn, int printablePagesOnCount, out IXpsPrintJob xpsPrintJob, out IXpsPrintJobStream documentStream, out IXpsPrintJobStream printTicketStream);

        [DllImport("XpsPrint.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
        public static extern int StartXpsPrintJob1(string printerName, string jobName, string outputFileName, IntPtr progressEvent, SafeWaitHandle completionEvent,
          out IXpsPrintJob xpsPrintJob,  out IXpsOMPackageTarget printContentReceiver);




        [DllImport("kernel32.dll")]
        public static extern bool Beep(int frequency, int duration);

        [DllImport("user32.dll")]
        public static extern bool MessageBeep(BeepType beepType);
        public enum BeepType
        {
            SimpleBeep = -1,
            IconAsterisk = 0x00000040,
            IconExclamation = 0x00000030,
            IconHand = 0x00000010,
            IconQuestion = 0x00000020,
            Ok = 0x00000000,
        }
    }


   
   

    [ComImport, Guid("E974D26D-3D9B-4D47-88CC-3872F2DC3585"), ClassInterface(ClassInterfaceType.None)]
    internal class XpsOMObjectFactory
    {
    }

    [ComImport, Guid("F9B2A685-A50D-4FC2-B764-B56E093EA0CA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IXpsOMObjectFactory
    {
        void CreatePackage();

        [return: MarshalAs(UnmanagedType.Interface)]
        IXpsOMPackage CreatePackageFromFile([MarshalAs(UnmanagedType.LPWStr)] string filename, bool reuseObjects);

        void CreatePackageFromStream();
        void CreateStoryFragmentsResource();
        void CreateDocumentStructureResource();
        void CreateSignatureBlockResource();
        void CreateRemoteDictionaryResource();
        void CreateRemoteDictionaryResourceFromStream();
        void CreatePartResources();
        void CreateDocumentSequence();
        void CreateDocument();
        void CreatePageReference();
        void CreatePage();
        void CreatePageFromStream();
        void CreateCanvas();
        void CreateGlyphs();
        void CreatePath();
        void CreateGeometry();
        void CreateGeometryFigure();
        void CreateMatrixTransform();
        void CreateSolidColorBrush();
        void CreateColorProfileResource();
        void CreateImageBrush();
        void CreateVisualBrush();
        void CreateImageResource();
        void CreatePrintTicketResource();
        void CreateFontResource();
        void CreateGradientStop();
        void CreateLinearGradientBrush();
        void CreateRadialGradientBrush();
        void CreateCoreProperties();
        void CreateDictionary();
        void CreatePartUriCollection();
        void CreatePackageWriterOnFile();
        void CreatePackageWriterOnStream();
        void CreatePartUri();
        void CreateReadOnlyStreamOnFile();
    }

    [ComImport, Guid("18C3DF65-81E1-4674-91DC-FC452F5A416F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IXpsOMPackage
    {
        void GetDocumentSequence();
        void SetDocumentSequence();
        void GetCoreProperties();
        void SetCoreProperties();
        void GetDiscardControlPartName();
        void SetDiscardControlPartName();
        void GetThumbnailResource();
        void SetThumbnailResource();
        void WriteToFile();

        void WriteToStream(IXpsPrintJobStream stream, bool optimizeMarkupSize);
    };

    // NOTE: It appears that the IID for IXpsPrintJobStream specified in XpsPrint.h -- 
    // MIDL_INTERFACE("7a77dc5f-45d6-4dff-9307-d8cb846347ca") -- is not correct, or the object
    // doesn't implement QueryInterface correctly. However, we can QI for ISequentialStream and
    // successfully (at least in Windows 7 SP1 x86) call the Close method as if it existed on that
    // interface.
    // That is, we obtain the ISequentialStream interface, but work with it as the IXpsPrintJobStream interface.
    // Thanks to http://stackoverflow.com/questions/6123507/xps-printing-from-windows-service for this tip.
    [ComImport, Guid("0C733A30-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IXpsPrintJobStream
    {
        // ISequentialStream methods
        void Read([MarshalAs(UnmanagedType.LPArray)] byte[] pv, uint cb, out uint pcbRead);
        void Write([MarshalAs(UnmanagedType.LPArray)] byte[] pv, uint cb, out uint pcbWritten);

        // IXpsPrintJobStream methods
        void Close();
    }

    [Guid("5ab89b06-8194-425f-ab3b-d7a96e350161")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IXpsPrintJob
    {
        void Cancel();
        void GetJobStatus(out XPS_JOB_STATUS jobStatus);
    }

    [StructLayout(LayoutKind.Sequential)]
    struct XPS_JOB_STATUS
    {
        public UInt32 jobId;
        public Int32 currentDocument;
        public Int32 currentPage;
        public Int32 currentPageTotal;
        public XPS_JOB_COMPLETION completion;
        public Int32 jobStatus; // UInt32
    };
    enum XPS_JOB_COMPLETION
    {
        XPS_JOB_IN_PROGRESS = 0,
        XPS_JOB_COMPLETED = 1,
        XPS_JOB_CANCELLED = 2,
        XPS_JOB_FAILED = 3
    }

    enum WAIT_RESULT
    {
        WAIT_OBJECT_0 = 0,
        WAIT_ABANDONED = 0x80,
        WAIT_TIMEOUT = 0x102,
        WAIT_FAILED = -1 // 0xFFFFFFFF
    }
    internal interface IXpsOMPackageTarget {
        int CreateXpsOMPackageWriter(out IOpcPartUri documentSequencePartName, out IXpsOMPrintTicketResource documentSequencePrintTicket, out IOpcPartUri discardControlPartName, out IXpsOMPackageWriter packageWriter);
    }

    internal interface IOpcPartUri
    {
          int ComparePartUri( out  IOpcPartUri partUri,  out int comparisonResult);
          int GetSourceUri(out IOpcPartUri sourceUri);
          int IsRelationshipsPartUri(out bool itRelationshipUri);

    }
    public static class GlobalMembers
    {
        //C++ TO C# CONVERTER TODO TASK: The implementation of the following method could not be found:
        //int AddPage([in]IXpsOMPage page, [in]XPS_SIZE advisoryPageDimensions, [in]IXpsOMPartUriCollection discardableResourceParts, [in]IXpsOMStoryFragmentsResource storyFragments, [in]IXpsOMPrintTicketResource pagePrintTicket, [in]IXpsOMImageResource pageThumbnail);
    }
    internal interface IXpsOMPackageWriter
    {
        void AddPage();
        void AddResource();
        void Close();
        void IsClosed();
        void StartNewDocument();
    }


    internal interface IXpsOMPrintTicketResource
    {
        int GetStream(out IStream stream);
        int SetContent(out IStream sourceStream, out IOpcPartUri partName);
    }
    [ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IStream
    {
        void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbRead);
        void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbWritten);
        void Seek(long dlibMove, uint dwOrigin, out long plibNewPosition);
        void SetSize(long libNewSize);
        void CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten);
        void Commit(uint grfCommitFlags);
        void Revert();
        void LockRegion(long libOffset, long cb, uint dwLockType);
        void UnlockRegion(long libOffset, long cb, uint dwLockType);
        void Stat(out STATSTG pstatstg, uint grfStatFlag);
        void Clone(out IStream ppstm);
    }

credit to http://faithlife.codes/blog/2011/12/printing-from-net35-in-windows7/

留言

這個網誌中的熱門文章

msdeploy include ApplicationPool setting and ignore recycle time

Invoke generic method