473,659 Members | 2,934 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Getting the default printer in 64-bit Vista

Hi,

I have used the code below to return the default printer in 32-bit WinXP
Pro, but now that I am running 64-bit Vista Business I'm getting an error:

using System.Drawing. Printing;

using (PrintDocument objPrintDocumen t = new PrintDocument() )
{
string strDefaultPrint er =
objPrintDocumen t.PrinterSettin gs.PrinterName;
}

The error message is: "No printers are installed." and which seems to come
from a method called HdevmodeInterna l

However, I have several printers installed, and the default printer is an
old HP LaserJet 5.

Does the above code not work on 64-bit Vista? The app in question is
compiled for x86...

Would I be better off using WMI to return the name of the default printer?

I've tried to find a solution in Google and MSDN, but haven't had much
luck...

Any assistance gratefully received.
--
http://www.markrae.net
Jun 8 '07 #1
13 9076
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:u5******** ******@TK2MSFTN GP04.phx.gbl...
Hi,

I have used the code below to return the default printer in 32-bit WinXP
Pro, but now that I am running 64-bit Vista Business I'm getting an error:

using System.Drawing. Printing;

using (PrintDocument objPrintDocumen t = new PrintDocument() )
{
string strDefaultPrint er =
objPrintDocumen t.PrinterSettin gs.PrinterName;
}

The error message is: "No printers are installed." and which seems to come
from a method called HdevmodeInterna l

However, I have several printers installed, and the default printer is an
old HP LaserJet 5.

Does the above code not work on 64-bit Vista? The app in question is
compiled for x86...

Would I be better off using WMI to return the name of the default printer?

I've tried to find a solution in Google and MSDN, but haven't had much
luck...

Any assistance gratefully received.
--
http://www.markrae.net


Works for me on Vista 64 and 32 bit. What happens if you make "Microsoft XPS
Document Writer" the default printer?

Willy.
Jun 9 '07 #2
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:%2******** ********@TK2MSF TNGP06.phx.gbl. ..
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:u5******** ******@TK2MSFTN GP04.phx.gbl...
>Hi,

I have used the code below to return the default printer in 32-bit WinXP
Pro, but now that I am running 64-bit Vista Business I'm getting an
error:

using System.Drawing. Printing;

using (PrintDocument objPrintDocumen t = new PrintDocument() )
{
string strDefaultPrint er =
objPrintDocume nt.PrinterSetti ngs.PrinterName ;
}

The error message is: "No printers are installed." and which seems to
come from a method called HdevmodeInterna l

However, I have several printers installed, and the default printer is an
old HP LaserJet 5.

Does the above code not work on 64-bit Vista? The app in question is
compiled for x86...

Would I be better off using WMI to return the name of the default
printer?

I've tried to find a solution in Google and MSDN, but haven't had much
luck...

Any assistance gratefully received.
--
http://www.markrae.net

Works for me on Vista 64 and 32 bit. What happens if you make "Microsoft
XPS Document Writer" the default printer?
Same thing... Incidentally, it works for me on 32-bit Vista... Did you try
it with a 32-bit app running on 64-bit Vista...?

Also, when I try to query objPrintDocumen t.PrinterSettin gs.PrinterName, it
returns "Default printer is not set.", though it definitely is...

The Exception generated still doesn't have any value for InnerException, and
the <Exception>.Tar getSite.Name is "HdevmodeIntern al" - I can't even find
that anywhere in Google!
--
http://www.markrae.net

Jun 9 '07 #3
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:u4******** ******@TK2MSFTN GP04.phx.gbl...
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:%2******** ********@TK2MSF TNGP06.phx.gbl. ..
>"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:u5******* *******@TK2MSFT NGP04.phx.gbl.. .
>>Hi,

I have used the code below to return the default printer in 32-bit WinXP
Pro, but now that I am running 64-bit Vista Business I'm getting an
error:

using System.Drawing. Printing;

using (PrintDocument objPrintDocumen t = new PrintDocument() )
{
string strDefaultPrint er =
objPrintDocum ent.PrinterSett ings.PrinterNam e;
}

The error message is: "No printers are installed." and which seems to
come from a method called HdevmodeInterna l

However, I have several printers installed, and the default printer is
an old HP LaserJet 5.

Does the above code not work on 64-bit Vista? The app in question is
compiled for x86...

Would I be better off using WMI to return the name of the default
printer?

I've tried to find a solution in Google and MSDN, but haven't had much
luck...

Any assistance gratefully received.
--
http://www.markrae.net

Works for me on Vista 64 and 32 bit. What happens if you make "Microsoft
XPS Document Writer" the default printer?

Same thing... Incidentally, it works for me on 32-bit Vista... Did you try
it with a 32-bit app running on 64-bit Vista...?
Yep, both X86 and X64 flavors work on 64-bit Vista Ultimate.

Note that I'm allways adding an application manifest to my executable
assemblies. If you don't add a manifest to an application that runs under
wow64, this application will get a virtualized view of the registry (part
off) and the file system (part off).

To prevent virtualization you have to add a manifest like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes "?>
<assembly xmlns="urn:sche mas-microsoft-com:asm.v1" manifestVersion ="1.0">
<assemblyIdenti ty version="1.0.0. 0"
name="MyApplica tion.app"></assemblyIdentit y>
<trustInfo xmlns="urn:sche mas-microsoft-com:asm.v2">
<security>
<requestedPrivi leges xmlns="urn:sche mas-microsoft-com:asm.v3">
<requestedExecu tionLevel
level="asInvoke r"></requestedExecut ionLevel>
</requestedPrivil eges>
</security>
</trustInfo>
</assembly>

save above contents in a file named "MyApplication. manifest", where
"MyApplicat ion" is the name of the assembly (not absolutely required any
name will do as manifest filename).
When done, run the following command:
mt -manifest MyApplication.m anifest -outputresource: MyApplication.e xe;#1

mt.exe is part of VS2005.

I'm not sure this will be of any help, but it's worth a try.

Willy.
Jun 9 '07 #4
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:uK******** ******@TK2MSFTN GP04.phx.gbl...
I'm not sure this will be of any help, but it's worth a try.
Didn't help, unfortunately.. .

However, I'm wondering if there's something more fundamental going on
here...

When I run e.g. Word 2007, it "sees" the collection of printers installed,
and selects the default one.

However, when I open a PDF in Acrobat Reader 8.0 and try to print it, I get
a MessageBox saying:

"Before you can perform print-related tasks such as page setup or printing a
document, you need to install a printer."

Maybe Word and Acrobat Reader are using different methods to interrogate the
collection if installed printers...?
--
http://www.markrae.net

Jun 9 '07 #5
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:un******** ******@TK2MSFTN GP04.phx.gbl...
However, I'm wondering if there's something more fundamental going on
here...
Also, when debugging the app in VS.NET 2005 and I force it to quit as soon
as the Exception is thrown, the Output window shows:

"A first chance exception of type
'System.Drawing .Printing.Inval idPrinterExcept ion' occurred in
System.Drawing. dll"
--
http://www.markrae.net

Jun 9 '07 #6
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:un******** ******@TK2MSFTN GP04.phx.gbl...
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:uK******** ******@TK2MSFTN GP04.phx.gbl...
>I'm not sure this will be of any help, but it's worth a try.

Didn't help, unfortunately.. .

However, I'm wondering if there's something more fundamental going on
here...

When I run e.g. Word 2007, it "sees" the collection of printers installed,
and selects the default one.

However, when I open a PDF in Acrobat Reader 8.0 and try to print it, I
get a MessageBox saying:

"Before you can perform print-related tasks such as page setup or printing
a
document, you need to install a printer."
This is basically the same error as yours.
I'm running AR 8.1.0 and everything works as expected.
Maybe Word and Acrobat Reader are using different methods to interrogate
the collection if installed printers...?
Probably they do.
Note that .NET uses PrintDlg from comdlg32.dll (SysWow64), probably Adobe
uses the same.

Could you try this?

// start of code X86 only!
using System;
using System.Componen tModel;
using System.Runtime. InteropServices ;

namespace Willys
{
[StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Auto, Pack=0x1)]
public class PRINTDLG
{
public int lStructSize;
public IntPtr hwndOwner;
public IntPtr hDevMode;
public IntPtr hDevNames;
public IntPtr hDC;
public int Flags;
public short nFromPage;
public short nToPage;
public short nMinPage;
public short nMaxPage;
public short nCopies;
public IntPtr hInstance;
public IntPtr lCustData;
public IntPtr lpfnPrintHook;
public IntPtr lpfnSetupHook;
public string lpPrintTemplate Name;
public string lpSetupTemplate Name;
public IntPtr hPrintTemplate;
public IntPtr hSetupTemplate;
}

class Program
{
[DllImport("comd lg32.dll", CharSet=CharSet .Auto, SetLastError=tr ue)]
static extern int PrintDlg([In, Out] PRINTDLG lppd);
[DllImport("kern el32.dll", CharSet=CharSet .Auto, SetLastError=tr ue,
ExactSpelling=t rue)]
public static extern IntPtr GlobalLock(Hand leRef handle);
[DllImport("kern el32.dll", CharSet=CharSet .Auto, SetLastError=tr ue,
ExactSpelling=t rue)]
public static extern bool GlobalUnlock(Ha ndleRef handle);
[DllImport("kern el32.dll", CharSet=CharSet .Auto, SetLastError=tr ue,
ExactSpelling=t rue)]
public static extern IntPtr GlobalFree(Hand leRef handle);

static void Main()
{
Console.WriteLi ne(GetDefaultPr interName());
}
private static PRINTDLG CreatePRINTDLG( )
{
PRINTDLG printdlg = new PRINTDLG();
printdlg.lStruc tSize = Marshal.SizeOf( typeof(PRINTDLG ));
printdlg.hwndOw ner = IntPtr.Zero;
printdlg.hDevMo de = IntPtr.Zero;
printdlg.hDevNa mes = IntPtr.Zero;
printdlg.Flags = 0x0;
printdlg.hwndOw ner = IntPtr.Zero;
printdlg.hDC = IntPtr.Zero;
printdlg.nFromP age = 0x1;
printdlg.nToPag e = 0x1;
printdlg.nMinPa ge = 0x0;
printdlg.nMaxPa ge = 0x270f;
printdlg.nCopie s = 0x1;
printdlg.hInsta nce = IntPtr.Zero;
printdlg.lCustD ata = IntPtr.Zero;
printdlg.lpfnPr intHook = IntPtr.Zero;
printdlg.lpfnSe tupHook = IntPtr.Zero;
printdlg.lpPrin tTemplateName = null;
printdlg.lpSetu pTemplateName = null;
printdlg.hPrint Template = IntPtr.Zero;
printdlg.hSetup Template = IntPtr.Zero;
return printdlg;
}
static string GetDefaultPrint erName()
{
PRINTDLG printdlg = CreatePRINTDLG( );
printdlg.Flags = 0x400; //PD_RETURNDEFAUL T
if (PrintDlg(print dlg) == 0)
return "No Default Printer Set";
IntPtr hDevNames = printdlg.hDevNa mes;
IntPtr handle = GlobalLock(new HandleRef(print dlg, hDevNames));
if (handle == IntPtr.Zero)
throw new Win32Exception( );
// calculate offset of dev names in DEVNAMES struct allocated by
PrintDlg
// X86 platforms only!!!!!!!!
int devOffset = Marshal.SystemD efaultCharSize *
Marshal.ReadInt 16((IntPtr) (((int) handle) + 2));
string name = Marshal.PtrToSt ringAuto((IntPt r) (((int) handle) +
devOffset));
GlobalUnlock(ne w HandleRef(print dlg, hDevNames));
GlobalFree(new HandleRef(print dlg, printdlg.hDevNa mes));
GlobalFree(new HandleRef(print dlg, printdlg.hDevMo de));
return name;
}
}
}
// end of code

If this doesn't work, you have a fundamental issue, not related to .NET.
Sure you can also give WMI a try.
Willy.

Jun 9 '07 #7
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:e5******** ******@TK2MSFTN GP05.phx.gbl...
Could you try this?
That returns "No Default Printer Set"
If this doesn't work, you have a fundamental issue, not related to .NET.
Hmm - that's a bit worrying... :-(
Sure you can also give WMI a try.
WMI works perfectly, however...

using (ManagementObje ctSearcher objMOS = new
ManagementObjec tSearcher("SELE CT * FROM Win32_Printer") )
{
Dictionary<stri ng, booldicResults = new Dictionary<stri ng, bool>();
using (ManagementObje ctCollection objMOC = objMOS.Get())
{
foreach (ManagementObje ct objMO in objMOC)
{
dicResults.Add( objMO["Name"].ToString(),
Convert.ToBoole an(objMO["Default"]));
}
}
return dicResults;
}
--
http://www.markrae.net

Jun 9 '07 #8
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:Or******** ******@TK2MSFTN GP05.phx.gbl...
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:e5******** ******@TK2MSFTN GP05.phx.gbl...
>Could you try this?

That returns "No Default Printer Set"
That means that the PrintDlg call returns 0, which means "failure" to get
the default printer..... which does not necessarily means there is no
default printer :-)

>If this doesn't work, you have a fundamental issue, not related to .NET.

Hmm - that's a bit worrying... :-(
>Sure you can also give WMI a try.

WMI works perfectly, however...

using (ManagementObje ctSearcher objMOS = new
ManagementObjec tSearcher("SELE CT * FROM Win32_Printer") )
{
Dictionary<stri ng, booldicResults = new Dictionary<stri ng, bool>();
using (ManagementObje ctCollection objMOC = objMOS.Get())
{
foreach (ManagementObje ct objMO in objMOC)
{
dicResults.Add( objMO["Name"].ToString(),
Convert.ToBoole an(objMO["Default"]));
}
}
return dicResults;
}
--
http://www.markrae.net

WMI does not use comdlg32.dll, anyway, it looks like there the issue is with
the 32bit version of the common dialog component or (more probably) one of
it's dependents. Mind to check the version installed in %windir%\SysWow 64? I
have 6.0.6000.16386, however I can't believe yours would be different.

Willy.
Jun 9 '07 #9
"Mark Rae" <ma**@markNOSPA Mrae.netwrote in message
news:Or******** ******@TK2MSFTN GP05.phx.gbl...
"Willy Denoyette [MVP]" <wi************ *@telenet.bewro te in message
news:e5******** ******@TK2MSFTN GP05.phx.gbl...
>Could you try this?

That returns "No Default Printer Set"
>If this doesn't work, you have a fundamental issue, not related to .NET.

Hmm - that's a bit worrying... :-(
>Sure you can also give WMI a try.

WMI works perfectly, however...

using (ManagementObje ctSearcher objMOS = new
ManagementObjec tSearcher("SELE CT * FROM Win32_Printer") )
{
Dictionary<stri ng, booldicResults = new Dictionary<stri ng, bool>();
using (ManagementObje ctCollection objMOC = objMOS.Get())
{
foreach (ManagementObje ct objMO in objMOC)
{
dicResults.Add( objMO["Name"].ToString(),
Convert.ToBoole an(objMO["Default"]));
}
}
return dicResults;
}
--
http://www.markrae.net


Note that you can simplify/optimize your query like this:

string DefaultPrinterN ame() {
string defaultPrinter = null;
SelectQuery q = new SelectQuery("se lect caption from win32_printer where
default = true");
using(Managemen tObjectSearcher searcher = new
ManagementObjec tSearcher(q))
{
foreach (ManagementObje ct printer in searcher.Get()) {
defaultPrinter = printer["Caption"].ToString();
}
}
return defaultPrinter;
}

Willy.

Jun 9 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
13011
by: Pablo | last post by:
Friends, how can i get the name of the default printer??. I'm working with winforms. VB,C#, nevermind. Thanks a lot Pablo
0
2579
by: Esmee | last post by:
Hi there, I have created an Access 2002 db which contains several reports. Some reports need to be printed on a Laserjet and others on a Labelprinter. One of my clients wants to be able to print the same reports to 3 different laserjets and to 3 different labelprinters. (They work with the db on 3 different units each with their own Laserjet and Labelprinter) For each unit there is a copy of all the reports. The client can make a unit...
1
11870
by: Bruce Wood | last post by:
I'm having a devil of a time calling DeviceCapabilities() in order to get the list of paper names / codes / sizes for a printer. Here is my code and the input it produces: static extern Int32 DeviceCapabilities( string device, string port, Int16 capability, out IntPtr outputBuffer,
3
3629
by: Geraldine Hobley | last post by:
Hello, How would you get and set the current default printer by using the system.drawing.printing class or any other class. Regards Geri
1
1446
by: Geraldine Hobley | last post by:
Hello, I have the following code that sets the default printer using the WMI (windows management system). ' Add a Reference to System.Management Dim moReturn As Management.ManagementObjectCollection Dim moSearch As Management.ManagementObjectSearcher Dim mo As Management.ManagementObject moSearch = New Management.ManagementObjectSearcher("Select * from
4
5997
by: Sean Shanny | last post by:
To all, Running into an out of memory error on our data warehouse server. This occurs only with our data from the 'September' section of a large fact table. The exact same query running over data from August or any prior month for that matter works fine which is why this is so weird. Note that June 2004 through today is stored in the same f_pageviews table. Nothing has changed on the server in the last couple of months. I upgraded...
3
17133
by: Panos | last post by:
Hi, is there a way that i could get the default printer of the system? I'm using VB.net 2001. There is a function in SDK called "GetDefaultPrinter", but i don't understand how to use it.
0
1609
by: Karthick_Microsoft | last post by:
Actually, in my ASP.Net application, i have a requirement of automatically changing the default printer. I did a OCX using VB and put it on the web page. The client machines do not have local printers but network printers (they have been mapped using Local Port pointing to \\machine\printer - this was suggested in a topic - for a reason that a network printer can be given a friendly name) - But when I click on Print from the browser...
1
5450
by: i8mypnuts | last post by:
Could someone please help? I am using the 'defaultprt.zip' tool provided by Ken Getz to change the default printer via VBA code (code below). My problem is that once the default printer has been changed, Access 2003 still directs the report to the former default printer. Access 2003 picks up the new default printer setting only after I have reopened the application. I have checked the default printer setting in the OS control panel and the...
5
2003
by: Glenn | last post by:
Hi We have a ASP.net app which calls into a web service which allow users to print stuff. At the moment they have to specify the printer. Apparently this is too much for our users, so I was wondering if there's a way of getting the default printer from their user profile? TIA Glenn
0
8427
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8332
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8746
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8627
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7356
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1975
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.