How to print 22 .xps files?
-
Saturday, April 28, 2012 7:14 PM
I have a program that produces 22 xps files every day. All the files are in the same directory. Currently the lady at the office clicks on a file, XPS Viewer opens, she prints the file on her printer and then close the XPS Viewer. She does this for all 22 files. I want to write a program that can find all the xps files in the directory and print each one.
I know how to get the filename of each xps file in the directory but for the life of me I have not been able to get even one to print. I found an example at the Microsoft library and tried it but there were so many errors that it would not compile.
Please help.
Thanks in advance.
Philip
All Replies
-
Saturday, April 28, 2012 7:57 PMProcess with a verb of print and the xps filename should send it to the default program to print. For example, if the file was "SomeFile.xps", you should be able to do this:dim p as new System.Diagnostics.Processp.StartInfo.Filename = "SomeFile.xps"p.StartInfo.Verb = "Print"p.Start()
--
Mike- Proposed As Answer by Frank L. SmithMicrosoft Community Contributor Saturday, April 28, 2012 8:06 PM
- Unproposed As Answer by Philip Potts Saturday, April 28, 2012 8:46 PM
-
Saturday, April 28, 2012 8:08 PM
Thanks Mike!
Your example ALMOST does what I want, but not quite. It will print each file in the directory but it requires the user to click on the "Print" button for each file. I want to be able to have each file in the directory print without needing any action from the user.
Philip
-
Saturday, April 28, 2012 8:21 PMType "How to: Programmatically Print XPS Files" in the bing box at the top of this page.
On the page that appears, click on "Remove all"
You can also type it in the search box on the Index tab of your help viewer in your IDE.- Edited by JohnWeinMicrosoft Community Contributor Saturday, April 28, 2012 8:24 PM
- Edited by JohnWeinMicrosoft Community Contributor Saturday, April 28, 2012 8:25 PM
-
Saturday, April 28, 2012 8:24 PMSorry, what I had suggested is how to emulate the user right-clicking a file in windows explorer and selecting "print". If the program "XPS Viewer" doesn't allow printing without this step of approving, I don't think you can override it. You may want to search if there is an update to the viewer, or an alternative package that allows what you need.
--
Mike -
Saturday, April 28, 2012 8:27 PM
Hi John,
Good to "talk" with you again. I found the program you point to prior to posting my question. That is the sample program that I could not get to run. Oh, how I wish it would because it would do exactly what I need. I'm not sure why it won't work. I tried it as a console application and a Windows Form application.. Either way there were several errors I could not figure out.
Thank you for your suggestion and I'll keep trying to get the sample to work. I have been at it all day though without much success.
Philip
I receive an error on the following line:
Dim localPrintServer As New LocalPrintServer()
Type "LocalPrintServer" not defined."
There are a few more lines with this same type error.
- Edited by Philip Potts Saturday, April 28, 2012 8:37 PM
-
Saturday, April 28, 2012 9:01 PM
I only found a few minor problems. You have to reference System.Printing. I also had a problem with "PrintJobException", so I removed the try...catch containing it.
Imports System.Threading Imports System.Printing Imports System.IO Class Program ' Added for clarity, but this line is redundant because MTA is the default. <System.MTAThreadAttribute> _ Friend Shared Sub Main(args As String()) ' Create the secondary thread and pass the printing method for ' the constructor's ThreadStart delegate parameter. The BatchXPSPrinter ' class is defined below. Dim printingThread As New Thread(AddressOf BatchXPSPrinter.PrintXPS) ' Set the thread that will use PrintQueue.AddJob to single threading. printingThread.SetApartmentState(ApartmentState.STA) ' Start the printing thread. The method passed to the Thread ' constructor will execute. printingThread.Start() End Sub 'end Main End Class 'end Program class Public Class BatchXPSPrinter Public Shared Sub PrintXPS() ' Create print server and print queue. Dim localPrintServer__1 As New LocalPrintServer() Dim defaultPrintQueue As PrintQueue = LocalPrintServer.GetDefaultPrintQueue() ' Prompt user to identify the directory, and then create the directory object. Console.Write("Enter the directory containing the XPS files: ") Dim directoryPath As [String] = Console.ReadLine() Dim dir As New DirectoryInfo(directoryPath) ' If the user mistyped, end the thread and return to the Main thread. If Not dir.Exists Then Console.WriteLine("There is no such directory.") Else ' If there are no XPS files in the directory, end the thread ' and return to the Main thread. If dir.GetFiles("*.xps").Length = 0 Then Console.WriteLine("There are no XPS files in the directory.") Else Console.WriteLine(vbLf & "Jobs will now be added to the print queue.") Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.") ' Batch process all XPS files in the directory. For Each f As FileInfo In dir.GetFiles("*.xps") Dim nextFile As [String] = directoryPath & "\" & f.Name Console.WriteLine("Adding {0} to queue.", nextFile) Dim xpsPrintJob As PrintSystemJobInfo = defaultPrintQueue.AddJob(f.Name, nextFile, False) ' end for each XPS file Next 'end if there are no XPS files in the directory End If End If 'end if the directory does not exist Console.WriteLine("Press Enter to end program.") Console.ReadLine() End Sub ' end PrintXPS method End Class ' end BatchXPSPrinter class- Marked As Answer by Philip Potts Sunday, April 29, 2012 12:19 PM
-
Sunday, April 29, 2012 2:59 AM
John,
I have encountered another problem: Imports System.Printing produces an error.
"Name space or type specified in the Imports 'System.Printing' doesn't contain any public member or cannot be found..."
I am doing this in a Windows Form application. Should I be using a console application?
Philip
Added
I found the solution to the Imports problem: I needed to add a reference to System.Printing to the project. However, I still don't know if this needs to be a console application or a windows form.
- Edited by Philip Potts Sunday, April 29, 2012 3:05 AM
-
Sunday, April 29, 2012 5:05 AMThe code I posted was a console app, but you should be able to use the class in a WPF app. It might be good idea to get the posted code working first before experimenting. How did you reference System.Printing?
-
Sunday, April 29, 2012 10:52 AMFrom this page, the namespace is specifically for WPF apps. The namespace is in a dll called ReachFramework.dll. I have no idea if you can get this code to work in a forms application as I have not seen the paragraph regarding a dll specifically for WPF before.
--
Mike -
Sunday, April 29, 2012 11:34 AM
How did you reference System.Printing?
I clicked on the Project tab and then Add Reference... On the screen that came up I clicked the .NET tab and then scrolled down to the System.Printing line. Clicked on that and then clicked on OK. After that the Imports error went away.
Now my problem is getting the code to run. I have tried it in both a console app and a form app. The problem is how to run the code. This is what I have:
Imports System.Threading Imports System.IO Imports System.Printing Module Module1 Sub main() End Sub Friend Class Program <System.MTAThreadAttribute()> Shared Sub Main(ByVal args() As String) ' Added for clarity, but this line is redundant because MTA is the default. ' Create the secondary thread and pass the printing method for ' the constructor's ThreadStart delegate parameter. The BatchXPSPrinter ' class is defined below. Dim printingThread As New Thread(AddressOf BatchXPSPrinter.PrintXPS) ' Set the thread that will use PrintQueue.AddJob to single threading. printingThread.SetApartmentState(ApartmentState.STA) ' Start the printing thread. The method passed to the Thread ' constructor will execute. printingThread.Start() End Sub 'end Main End Class 'end Program class Public Class BatchXPSPrinter Public Shared Sub PrintXPS() ' Create print server and print queue. Dim localPrintServer As New LocalPrintServer() Dim defaultPrintQueue As PrintQueue = localPrintServer.GetDefaultPrintQueue() Dim directoryPath As String = "C:\Users\Philip\Documents\WP Files" Dim dir As New DirectoryInfo(directoryPath) ' If the user mistyped, end the thread and return to the Main thread. If Not dir.Exists Then Console.WriteLine("There is no such directory.") Else ' If there are no XPS files in the directory, end the thread ' and return to the Main thread. If dir.GetFiles("*.xps").Length = 0 Then Console.WriteLine("There are no XPS files in the directory.") Else Console.WriteLine(vbLf & "Jobs will now be added to the print queue.") Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.") ' Batch process all XPS files in the directory. For Each f As FileInfo In dir.GetFiles("*.xps") Dim nextFile As String = directoryPath & "\" & f.Name Console.WriteLine("Adding {0} to queue.", nextFile) Next f ' end for each XPS file End If 'end if there are no XPS files in the directory End If 'end if the directory does not exist End Sub ' end PrintXPS method End Class ' end BatchXPSPrinter class End Module
As is the program runs and then ends. This is because the program never reaches the part that does the actual work. If I remove the Sub Main() I get an error. Any suggestions?
Philip
-
Sunday, April 29, 2012 11:36 AMFrom this page, the namespace is specifically for WPF apps. The namespace is in a dll called ReachFramework.dll. I have no idea if you can get this code to work in a forms application as I have not seen the paragraph regarding a dll specifically for WPF before.
--
MikeThanks again Mike.
I have never used a WPF app but this might be a good time to try.
Philip
-
Sunday, April 29, 2012 11:54 AM
"As is the program runs and then ends. This is because the program never reaches the part that does the actual work. If I remove the Sub Main() I get an error. Any suggestions?"
Which error message do you get? No directory or no XPS files? Ensure that the directory name is typed corretly and that it contains XPS files.
The code I posted should perform Identically to the C# code in the How to. It does for me in SharpDevelop which I used for the conversion. I notice that you don't copy and paste the code, but modify it in some random manner. If you start a Console Application and paste the code I posted in place of the code in the application, it should do what you want. When you get it working, you can modify it to run without having to enter the directory.
If you run the program as posted, you should get a console screen similar to this:
- Edited by JohnWeinMicrosoft Community Contributor Sunday, April 29, 2012 12:08 PM
-
Sunday, April 29, 2012 12:19 PM
Success!!!
Thank you all so VERY much. I tried this and that and finally it is working. I got the console app to work but I'm not really sure why. I removed the Sub Main() and the program started working. The other times I tried this I got an error message saying Sub Main() could not be found.
So, John and Mike, I am thankful that these forums have folks like you to assist folks like me.
Philip

