Re: Printing Issue
- From: "Alex Clark" <alex@xxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Thu, 8 Sep 2005 00:55:15 +0100
Hi Jeffrey,
I've submitted it as a bug report to MSDN Online Feedback with all necessary
information. After some more testing in my office I've deduced it may be
something to do with account impersonation, ie using the "Run As" command
rather than logging in directly as the test account and running it from
that.
My customer's been having this problem with their users running the app
through Citrix/Remote Desktop, which I assume is essentially impersonating
the user that logs in via it. Maybe it's not finding a default printer in
the user's profile settings until they've physically logged in on the
console?
Thanks,
Alex Clark
""Jeffrey Tan[MSFT]"" <v-jetan@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:qvLsw93sFHA.3544@xxxxxxxxxxxxxxxxxxxxxxxx
> Hi Alex ,
>
> Thanks for your feedback.
>
> I have created a test Power Users account on my machine, then test your
> sample code in this account. Yes, I can reproduce out this problem on my
> side. This exception occurs in PrintPreviewDialog.CreateHandle.
>
> If we use Reflector to view the source code, we will see that:
> protected override void CreateHandle()
> {
> if ((this.Document != null) &&
> !this.Document.PrinterSettings.IsValid)
> {
> throw new
> InvalidPrinterException(this.Document.PrinterSettings);
> }
> base.CreateHandle();
> }
>
> Then I added the test code:
> bool f=this.printDocument1.PrinterSettings.IsValid;
>
> For the test account, the result is false, which caused out the
> InvalidPrinterException exception.
>
> Further invest in System.Drawing.Printing.PrinterSettings.IsValid in
> Reflector, I got the following code:
> public bool IsValid
> {
> get
> {
> return (this.DeviceCapabilities(0x12, IntPtr.Zero, -1) != -1);
> }
> }
>
> private int DeviceCapabilities(short capability, IntPtr pointerToBuffer,
> int defaultValue)
> {
> IntSecurity.AllPrinting.Assert();
> string text1 = this.PrinterName;
> CodeAccessPermission.RevertAssert();
> IntSecurity.UnmanagedCode.Assert();
> return this.FastDeviceCapabilities(capability, pointerToBuffer,
> defaultValue, text1);
> }
>
> private int FastDeviceCapabilities(short capability, IntPtr
> pointerToBuffer, int defaultValue, string printerName)
> {
> int num1 = SafeNativeMethods.DeviceCapabilities(printerName,
> this.OutputPort, capability, pointerToBuffer, IntPtr.Zero);
> if (num1 == -1)
> {
> return defaultValue;
> }
> return num1;
> }
>
> After setting breakpoing in these methods one-by-one(you should setup the
> debug symbols correctly, also, I used Win2003 RunAs function to run VS.net
> under the test accout, so that I can do debugging under this test
> account),
> I find that DeviceCapabilities Win32 API failed and returns -1. Calling
> System.Runtime.InteropServices.Marshal.GetLastWin32Error(), I got the
> error
> message below: "The printer name is invalid".
>
> It seems that PrinterSettings.PrinterName property returns the incorrect
> printer name. Then I checked into the PrinterName property, I get these:
>
> public string get_PrinterName()
> {
> IntSecurity.AllPrinting.Demand();
> return this.PrinterNameInternal;
> }
>
> private string get_PrinterNameInternal()
> {
> if (this.printerName == null)
> {
> return PrinterSettings.GetDefaultPrinterName();
> }
> return this.printerName;
> }
>
> private static string GetDefaultPrinterName()
> {
> IntSecurity.UnmanagedCode.Assert();
> SafeNativeMethods.PRINTDLG printdlg1 =
> PrinterSettings.CreatePRINTDLG();
> printdlg1.Flags = 0x400;
> if (!SafeNativeMethods.PrintDlg(printdlg1))
> {
> return SR.GetString("NoDefaultPrinter");
> }
> IntPtr ptr1 = printdlg1.hDevNames;
> IntPtr ptr2 = SafeNativeMethods.GlobalLock(new HandleRef(printdlg1,
> ptr1));
> if (ptr2 == IntPtr.Zero)
> {
> throw new Win32Exception();
> }
> string text1 = PrinterSettings.ReadOneDEVNAME(ptr2, 1);
> SafeNativeMethods.GlobalUnlock(new HandleRef(printdlg1, ptr1));
> ptr2 = IntPtr.Zero;
> SafeNativeMethods.GlobalFree(new HandleRef(printdlg1,
> printdlg1.hDevNames));
> SafeNativeMethods.GlobalFree(new HandleRef(printdlg1,
> printdlg1.hDevMode));
> return text1;
> }
>
> I finally get that the SafeNativeMethods.PrintDlg return false, so no
> default printer name is returned(returned by
> SR.GetString("NoDefaultPrinter"); statement).
>
> SafeNativeMethods.PrintDlg is a Win32 API, which .Net p/invoked it. Then I
> write a MFC application to test this API in Win32 world:
>
> void CMFCPrintDlgTestDlg::OnBnClickedButton1()
> {
> PRINTDLG printdlg1;
> HWND hwnd;
>
> // Initialize PRINTDLG
> ZeroMemory(&printdlg1, sizeof(printdlg1));
>
> printdlg1.lStructSize = 0x42;
> printdlg1.hwndOwner = 0;
> printdlg1.hDevMode = 0;
> printdlg1.hDevNames = 0;
> printdlg1.Flags = 0;
> printdlg1.hwndOwner = 0;
> printdlg1.hDC = 0;
> printdlg1.nFromPage = 1;
> printdlg1.nToPage = 1;
> printdlg1.nMinPage = 0;
> printdlg1.nMaxPage = 0x270f;
> printdlg1.nCopies = 1;
> printdlg1.hInstance = 0;
> printdlg1.lCustData = 0;
> printdlg1.lpfnPrintHook = NULL;
> printdlg1.lpfnSetupHook = NULL;
> printdlg1.lpPrintTemplateName = NULL;
> printdlg1.lpSetupTemplateName = NULL;
> printdlg1.hPrintTemplate = 0;
> printdlg1.hSetupTemplate = 0;
> printdlg1.Flags = 0x400;
>
> if (PrintDlg(&printdlg1)==TRUE)
> {
> MessageBox("Succeeded!");
> DeleteDC(printdlg1.hDC);
> }
> else
> {
> char buf[50];
> wsprintf(buf, "error: %d",GetLastError());
> MessageBox(buf, buf);
> }
> }
> Testing with the test account, I also can reproduce out the problem. Also,
> the key point is for setting PRINTDLG.Flags to 0x400, which is
> PD_RETURNDEFAULT const.
>
> Yes, after enabling "Manage Documents" permission on the printer for test
> account, the problem will go away. But I am not sure why PrintDlg with
> PD_RETURNDEFAULT require "Manage Documents" permission.
>
> Currently, I do not think there is any good solution for this issue, maybe
> we have to setup "Manage Documents" permission for all the non-admin
> accounts.(Yes, you can documented this in your application)
>
> Finally, if you want to submit a bug for microsoft, I suggest you contact
> Microsoft PSS for it.
>
> You can contact Microsoft Product Support by contacting us at
> 1-(800)936-5800 or by choosing one of the options listed at
> http://www.microsoft.com/services/microsoftservices/supp.mspx
>
> Hope this information helps
>
> Best regards,
> Jeffrey Tan
> Microsoft Online Partner Support
> Get Secure! - www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.
>
.
- Follow-Ups:
- Re: Printing Issue
- From: "Jeffrey Tan[MSFT]"
- Re: Printing Issue
- References:
- Printing Issue
- From: Alex Clark
- Re: Printing Issue
- From: Collin Bennett
- Re: Printing Issue
- From: Alex Clark
- Re: Printing Issue
- From: "Jeffrey Tan[MSFT]"
- Printing Issue
- Prev by Date: How to display multi-dimensional array in PropertyGrid
- Next by Date: Re: DataGrid ReadOnly and NullText do not work
- Previous by thread: Re: Printing Issue
- Next by thread: Re: Printing Issue
- Index(es):
Loading