PrintDocument.Print() throws a Win32Exception - c#

I'm getting a strange exception from the following code:
var printDialog = new PrintDialog();
printDialog.ShowDialog();
var printDocument = new PrintDocument { DefaultPageSettings = { Landscape = true, PrinterSettings = new PrinterSettings { PrinterName = printDialog.PrintQueue.Name } } };
var updateResult = new UpdateResult<Image>(UpdateType.Print) { Success = true };
foreach (string location in fileLocation)
{
try
{
_printImage = Image.FromFile(location);
printDocument.PrintPage += PrintRequest;
}
catch (Exception exception)
{
//various error handling code here
}
}
printDocument.Print();
The final line is throwing a Win32Exception with the detail "The handle is invalid", according to the msdn documentation the only exception that should be thrown is printer not found. The exception seems to be to be some sort of driver/non framework exception.
When I select my printer (Lexmark T640, setup to print directly to the printer port) the code prints fine, but selecting either of the other two printers I have access to (another T640, or a dell colour) the code fails.
The other two printers are setup to print through our central print server, but I didn't think this should make any difference.
Can anyone give me any pointers?
Edit: Just tried it with printDialog.PrintQueue.Fullname and the behaviour is no different. Substituting in a garbage printer name throws an InvalidPrinterException as expected, suggesting it has found the printer, but seems to fail.

Try setting the target printer as the default printer (if it isn't already) and see if it still happens

For #Matt's benefit.
I didn't manage to figure out what the issue was in the end, could well be something to do with the configuration of our network but that's out of my hands.
Instead I used a different method, I used CommonDialogClass.ShowPhotoPrintingWizard() which is part of Interop.WIA as below.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms630492%28v=vs.85%29.aspx
This hands over the process to the photo printing wizard and I've not had any issues since.

I got this exception only when printing multiple documents. My solutions was to add
printDocument.Dispose(); after printDocument.Print();.

Related

C# PrintQueue AddJob printingHandle throws null exception

I'm trying to print a file with C#. I have made some headway in listing off all the printers and then wrote some simple logic to select the correct printer:
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections }).ToList();
int count = 0;
foreach (var q in queues)
{
Console.WriteLine(count++ + " " + q.Name);
}
int iSelection = 0;
while (true)
{
Console.Write("Select printer: ");
string selection = Console.ReadLine();
if (int.TryParse(selection, out iSelection) && iSelection >= 0 && iSelection < queues.Count())
{
break;
}
else
{
Console.WriteLine("Bad selection, try again.");
}
}
The next step, as for the posts I've seen on this site, is that you need to select the specific queue, and then add a job, grab the job stream, and write to the stream (at least that's how I want to try to do it, unless it's wrong?)
var queue = queues[iSelection];
var job = queue.AddJob(#".\Test.txt");
var stream = job.JobStream;
var file = File.ReadBytes(#".\Test.txt");
stream.Write(file, 0, file.Length);
When I do this, the program crashes at the line with AddJob. Specifically,
System.ArgumentNullException: 'Value cannot be null, Parameter name: printingHandler'
Now, I think I understand what the issue is. I had been playing with System.Drawing.Printing.PrintDocument yesterday, but I am trying to find a solution that allows me to print files, rather than manually draw them out and them print them. Ultimately, the goal in the future is to be able to print out text and PDF files (I was hoping that this solution would allow me to open a PDF file and dump the bytes into this stream, but I don't know if that's the correct way to this?)
Anyway, the exception I got I think is something similar to PrintDocument's PrintPageEventHandler, I need to add a callback to the PrintQueue somehow that tells it the font, color, font size, etc. Problem is that I see nothing for PrintQueue that allows me to add a handle for it to fix this issue.
What can I do to fix this exception?
I was having this issue as well. Eventually I found out that we need to call into Refresh() of the selected PrintQueue instance and before calling AddJob().

PosExplorer - barcode scanner - getting error 'Root element is missing' after scanner.Open()

I am programming an application in WPF which initializes posExplorer on a particular page, acquires the required scanner and then open and listen on DataEvent handler. It already worked and there wasn't any problem.
Then it suddenly (yep, suddenly) began to throw exception:
An exception of type 'System.Exception' occurred in HHSO4NET.dll but was not handled in user code...
Something like 'Root element is missing' [from Czech translation, which I can't change]
And yes, Barcode scanner was connected into computer. I already tried to reinstall pos for net 1.12, but still the same error.
There is code behind this:
Private PosExplorer posExplorer = new PosExplorer ();
Private Scanner scan;
PosExplorer.DeviceAddedEvent + = new
DeviceChangedEventHandler(posExplorer_DeviceAddedEvent);
Var deviceCollection = posExplorer.GetDevices (DeviceType.Scanner);
Foreach (DeviceInfo dInfo in deviceCollection)
{
If (dInfo.Type == "Scanner" && dInfo.ServiceObjectName == "HoneywellScannerSO")
{
If (dInfo.LogicalNames.Length> 0)
{
Devicess.Add (dInfo);
}
}
}
Scan = (Scanner) posExplorer.CreateInstance (devicess [0]);
If (! (Scan.State == ControlState.Idle))
{
Scan.Open (); //AFTER THAT IT FAILS
Scan.Claim (0);
Scan.DeviceEnabled = true;
Scan.DataEvent + = new DataEventHandler (activeScanner_DataEvent);
Scan.DataEvent = true;
Scan.DecodeData = true;
}
Can somebody tell me, how is possible that it worked and later without any modification in this code it do not work? Thanks for your answers.
Well, after a few days I finally solved it. It required software reinstal from Honeywell - POS4NET Configuration utility. Then remove and again add scanner on specified port and it running. How simple, right? But still dont know why it happened.

SharePoint ClientContext.ExecuteQuery works in c# application but crashes in DLL

I have written C# code to search for specific file types in SharePoint lists within a site and display the file names in a listview.
The code works perfectly well in a C# windows application, but when it is compiled into a C# DLL and called from a Delphi2007 application it crashes when it hits the first call to ClientContext.ExecuteQuery(). There is no exception or error message - the Delphi application just stops running.
The really weird part is that my Delphi test application has a web browser component, and if I use that to navigate to the top level list on the site the DLL then works OK.
The question therefore is why does the first ExecuteQuery call fail in the DLL if I haven't logged on to the site first?
This is the C# code:
public void ListFiles()
{
string LContains = "<Contains><FieldRef Name='FileLeafRef'/> <Value Type ='Text'>{0}</Value></Contains>";
string LNotEqual = "<Contains><FieldRef Name='FileLeafRef'/><Value Type ='Text'>{0}</Value></Contains>";
string LWhereQuery = "";
switch (comboFileType.SelectedIndex)
{
case 0: LWhereQuery = string.Format(LContains, ".DOC"); break;
case 1: LWhereQuery = string.Format(LContains, ".PDF"); break;
case 2: LWhereQuery = string.Format(LNotEqual, "xxxx"); break;
}
Uri LUri = new Uri(SharePointURL);
using (SP.ClientContext LContext = new SP.ClientContext(SharePointURL))
{
System.Net.CredentialCache cc = new System.Net.CredentialCache();
if (!string.IsNullOrEmpty(Domain))
cc.Add(LUri, AuthenticationType, new System.Net.NetworkCredential(UserName, Password, Domain));
else
cc.Add(LUri, AuthenticationType, new System.Net.NetworkCredential(UserName, Password));
LContext.Credentials = cc;
LContext.AuthenticationMode = SP.ClientAuthenticationMode.Default;
var LWeb = LContext.Web;
lvItems.BeginUpdate();
try
{
try
{
SP.List LList = LWeb.Lists.GetByTitle(DefaultListName);
SP.CamlQuery LQuery = new SP.CamlQuery();
LQuery.ViewXml = "<View Scope='RecursiveAll'><Query><Where>"
+ LWhereQuery
+ "</Where></Query><RowLimit> 30 </RowLimit></View>";
SP.ListItemCollection LItems = LList.GetItems(LQuery);
LContext.Load(LItems);
LContext.ExecuteQuery(); **<<<< Crash happens here**
foreach (SP.ListItem LItem in LItems)
{
SP.File LFile = LItem.File;
LContext.Load(LFile);
LContext.ExecuteQuery();
var LViewItem = new ListViewItem();
try { LViewItem.Text = LFile.Name; }
catch { LViewItem.Text = "!Error"; }
try { LViewItem.SubItems.Add(LFile.TimeLastModified.ToString()); }
catch { LViewItem.SubItems.Add("!Error"); }
if (LFile.CheckOutType != Microsoft.SharePoint.Client.CheckOutType.None)
{
try { LViewItem.SubItems.Add(LFile.CheckedOutByUser.LoginName); }
catch { LViewItem.SubItems.Add("!Error"); }
}
else
LViewItem.SubItems.Add("Not checked out.");
try { LViewItem.Tag = LFile.ServerRelativeUrl; }
catch { LViewItem.Tag = "!Error"; }
lvItems.Items.Add(LViewItem);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex);
}
}
finally
{
lvItems.EndUpdate();
}
}
The code is in the .cs of a dialog form in the DLL. The form displays as it should and the crash only happens when I click a button to do the search.
I put some debug code in to check all the string params etc. (by writing them to a text file) and they are all OK.
I tried debugging the DLL from VS by specifying the D2007 app as the 'startup external program' but I can't get breakpoints to work and at the point where it crashes it says: An unhandled exception of type 'System.StackOverflowException' occurred in Microsoft.SharePoint.Client.Runtime.dll and suggests I might have an infinite recursive call but, as mentioned earlier, the code all works perfectly if I have already logged into the site and browsed to the top level list, so i don't think it is a recursive call.
UPDATE: I got the debugging to work by copying the Delphi exe to the same directory as the DLL.
I've tried using the ExceptionHandlingScope but it hasn't helped. This is how it looks when it crashes:
The scope has no exception and the errormessage is blank. I tried a few connotations of what was inside the scope but to no avail.
The whole code block is in a try..catch and I've tried wrapping the ExecuteQuery line in it's own try..catch as well, but nothing catches it. The app crashes out every time when I hit continue.
I've also tried putting an execute query before loading the web but it still crashes out.
I'm thinking this has to be something to do with credentials? If I deliberately put the wrong username I get a polite '401 Unauthorized' back and no crash. And if I'm already logged in it doesn't crash either?
After trying the C# test application I tried the same with Delphi XE8 and that also worked, so in the end I've resorted to writing an intermediate DLL in XE8.
I noticed that when importing the TLB from the C# DLL into XE8 it behaved differently from D2007 in that it complained about other missing TLB's when building - notably the system.windows.forms library (and some dependencies). I'm not sure if this has any bearing on XE8 working and D2007 failing, but hopefully it well help anyone else needing a workaround.

Printing with XPSDocumentWritter on an Epson printer PrintQueue

We have an application that have a print function that works well on all printers except some products from Epson on Windows 8.
I've manage to make a minimal sample that reproduce the problem.
Call the following method, providing it with the full path to a correct xps file.
private void Print(string xpsFilename)
{
if (string.IsNullOrEmpty(xpsFilename))
{
return;
}
PrintDialog printDialog = new PrintDialog();
printDialog.ShowDialog();
PrintQueue defaultPrintQueue = printDialog.PrintQueue;
try
{
// This is were it seems to fail for some Epson printers: no job in spooler, no print ...
PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob("Print through 'AddJob' on PrintQueue", xpsFilename, false);
}
catch (PrintJobException printJobException)
{
Console.WriteLine("{0} Could not be added to the print queue.", xpsFilename);
Console.WriteLine(printJobException.Message);
}
catch (Exception exception)
{
Console.WriteLine("{0} Unknown error:", xpsFilename);
Console.WriteLine(exception.Message);
}
}
You will see that if you choose an Epson printer no job will appear in the spooler whereas it will work with any other printer.
Does anyone has an idea why it's not printing (the job does not even appears in the spool) ?
In the real application we do not use xps file but rather use a paginator, but for the sample purpose it's simpler and fail too ...
Thanks for any help.

Getting an exception as "The parameter is incorrect.\r\n" while moving file

I have written a code to move a file as follows
private void Move_Click(object sender, EventArgs e)
{
string strOrgpath = string.Empty, strNewpath = string.Empty;
strOrgpath = tvwACH.SelectedNode.ToString();
string strPath = strOrgpath.Substring(10);
FolderBrowserDialog folderborwser1 = new FolderBrowserDialog();
if (folderborwser1.ShowDialog() == DialogResult.OK)
{
try
{
strNewpath = folderborwser1.SelectedPath;
File.Move(strPath, strNewpath);
}
catch (Exception ex)
{
}
}
}
But i am getting the exception as i mentioned can any one tell why and some times i am getting the error as access to the path is denied
Make sure your substring call returns the correct result. If possible, use static methods from the Path class instead. Take a look at the MSDN page for File.Move and pay attention to what parameters are expected -- you should provide two valid full file names (e.g. C:\Blah\myFile.txt).
"Access denied" error message might happen if the user picks a folder they don't have write access to in the folder browser dialog. That's a scenario you'll have to handle in your code, perhaps by catching the UnauthorizedAccessException.
Update: the destination file should also point to a filename. So you'll need to do something like this:
var origFileName = Path.GetFileName(strPath);
strNewpath = Path.Combine(folderborwser1.SelectedPath, origFileName);
File.Move(strPath, strNewpath);
Without seeing the values that are being used in your application at run-time, I'm guessing tvwACH.SelecteNode.ToString() or strOrgpath.Substring(10) is not a valid File System path.
You should Debug your application and set a breakpoint to see what those values are (and post them if it's not obvious what your problem is at that point).

Categories