"Mark Rae" <ma**@markNOSPAMrae.netwrote in message
news:un**************@TK2MSFTNGP04.phx.gbl...
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:uK**************@TK2MSFTNGP04.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.ComponentModel;
using System.Runtime.InteropServices;
namespace Willys
{
[StructLayout(LayoutKind.Sequential, 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 lpPrintTemplateName;
public string lpSetupTemplateName;
public IntPtr hPrintTemplate;
public IntPtr hSetupTemplate;
}
class Program
{
[DllImport("comdlg32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int PrintDlg([In, Out] PRINTDLG lppd);
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true,
ExactSpelling=true)]
public static extern IntPtr GlobalLock(HandleRef handle);
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true,
ExactSpelling=true)]
public static extern bool GlobalUnlock(HandleRef handle);
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true,
ExactSpelling=true)]
public static extern IntPtr GlobalFree(HandleRef handle);
static void Main()
{
Console.WriteLine(GetDefaultPrinterName());
}
private static PRINTDLG CreatePRINTDLG()
{
PRINTDLG printdlg = new PRINTDLG();
printdlg.lStructSize = Marshal.SizeOf(typeof(PRINTDLG));
printdlg.hwndOwner = IntPtr.Zero;
printdlg.hDevMode = IntPtr.Zero;
printdlg.hDevNames = IntPtr.Zero;
printdlg.Flags = 0x0;
printdlg.hwndOwner = IntPtr.Zero;
printdlg.hDC = IntPtr.Zero;
printdlg.nFromPage = 0x1;
printdlg.nToPage = 0x1;
printdlg.nMinPage = 0x0;
printdlg.nMaxPage = 0x270f;
printdlg.nCopies = 0x1;
printdlg.hInstance = IntPtr.Zero;
printdlg.lCustData = IntPtr.Zero;
printdlg.lpfnPrintHook = IntPtr.Zero;
printdlg.lpfnSetupHook = IntPtr.Zero;
printdlg.lpPrintTemplateName = null;
printdlg.lpSetupTemplateName = null;
printdlg.hPrintTemplate = IntPtr.Zero;
printdlg.hSetupTemplate = IntPtr.Zero;
return printdlg;
}
static string GetDefaultPrinterName()
{
PRINTDLG printdlg = CreatePRINTDLG();
printdlg.Flags = 0x400; //PD_RETURNDEFAULT
if (PrintDlg(printdlg) == 0)
return "No Default Printer Set";
IntPtr hDevNames = printdlg.hDevNames;
IntPtr handle = GlobalLock(new HandleRef(printdlg, 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.SystemDefaultCharSize *
Marshal.ReadInt16((IntPtr) (((int) handle) + 2));
string name = Marshal.PtrToStringAuto((IntPtr) (((int) handle) +
devOffset));
GlobalUnlock(new HandleRef(printdlg, hDevNames));
GlobalFree(new HandleRef(printdlg, printdlg.hDevNames));
GlobalFree(new HandleRef(printdlg, printdlg.hDevMode));
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.