petersoftware

Hi everyone,

We have been working with XPS for almost a year. We have migrated our product from PCL to XPS and we launched the latest version in April this year. The product is working really well and sales are ok, but the biggest problem we are coming up against is the lack on a standard XPS Print Driver that will allow our customer to generate an XPS file from a generic application without being prompted for a filename.

This issue has been posted about many times, by many users of this forum. Within these posts there have been many suggestions including capturing the MXDW Print Dialog and filling in the values and clicking the button automatically (I have tried this and it does not look very professional). There has also be some good suggestions from the Microsoft XPS gurus on how to work around this issue for particular applications.

However, when a product is sold that takes in an XPS document, the customer expects to be able to easily create this XPS document. We would have expected by now that either Microsoft or a third party would have developed a reliable XPS Printer Driver that does not need to prompt for a filename, and would infact work like traditional PCL or PS drivers. For example a PCL driver can be set with its ports as "C:\test.pcl" and all output to that printer will be created in this file. No dialogs, no mess. If the user wishes this to be dynamic then they can purchase some low cost tools that will change the filename to be unique or match the name of the calling application.

I would be very keep to know whether this is on the drawing board at Microsoft or any other company, any if not whether there was a particulat reason for this.

Thank you for your time.



Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Robert Simpson

There is a messy way to do this that doesn't involve the Save As dialog.

Download the Detours SDK from http://research.microsoft.com/sn/detours/

A commercial license is available, but I've no idea what it costs.

Create a new DLL project, include the detours library, and inside it hook the StartDoc() function. Also export a function so you can install/uninstall a CBTHook when your main application starts. This will install the DLL in the address space of GUI apps running while your program is active and cause StartDoc() to get hooked for all those applications.

In your hooked StartDoc() function, do some sort of RPC or messaging with your application to fetch the filename, then fill it in.

I think this will work ...

Code Snippet

#include "Detours.h"

static HHOOK g_hook = NULL; // Something to hold the CBT hook handle

static HMODULE g_dll; // This DLL

// Functions wer'e detouring

static int (WINAPI *StartDocA_real)(__in HDC hdc, __in CONST DOCINFOA *lpdi) = StartDocA;

static int (WINAPI *StartDocW_real)(__in HDC hdc, __in CONST DOCINFOW *lpdi) = StartDocW;

int WINAPI StartDocA_hook(__in HDC hdc, __in DOCINFOA *lpdi)

{

LPCSTR pszTemp;

CHAR szPrintFilename[MAX_PATH];

int ret;

// TODO : RPC with your main app here to fill in szPrintFilename as an ANSI string

pszTemp = lpdi->lpszOutput;

lpdi->lpszOutput = szPrintFilename;

ret = StartDocA_real(hdc, lpdi);

lpdi->lpszOutput = pszTemp;

return ret;

}

int WINAPI StartDocW_hook(__in HDC hdc, __in DOCINFOW *lpdi)

{

LPCWSTR pszTemp;

WCHAR szPrintFilename[MAX_PATH];

int ret;

// TODO : RPC with your main app here to fill in szPrintFilename as an Unicode string

pszTemp = lpdi->lpszOutput;

lpdi->lpszOutput = szPrintFilename;

ret = StartDocW_real(hdc, lpdi);

lpdi->lpszOutput = pszTemp;

return ret;

}

// Empty CBTHook, existing only as a means to get this DLL in the address space of

// apps running on the system

LRESULT __declspec(dllexport) CALLBACK CBTHook(int nCode, WPARAM wParam, LPARAM lParam)

{

if (nCode < 0) return CallNextHookEx(g_hook, nCode, wParam, lParam);

return 0;

}

// External set/free functions to set and clear the CBT Hook

extern "C"

__declspec(dllexport) void WINAPI SetHook()

{

g_hook = SetWindowsHookEx(WH_CBT, CBTHook, g_dll, 0);

}

extern "C"

__declspec(dllexport) void WINAPI FreeHook()

{

if (g_hook)

{

UnhookWindowsHookEx(g_hook);

g_hook = NULL;

}

}

// Entrypoint, which also detours the StartDoc API's

BOOL APIENTRY DllMain( HMODULE hModule, DWORD dwReason, LPVOID /*lpReserved*/)

{

if (dwReason == DLL_PROCESS_ATTACH)

{

g_dll = hModule;

// Detour the StartDoc API's

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourAttach(&(PVOID&)StartDocA_real, StartDocA_hook);

DetourAttach(&(PVOID&)StartDocW_real, StartDocW_hook);

DetourTransactionCommit();

}

else if (dwReason == DLL_PROCESS_DETACH)

{

// Remove the detours of the StartDoc API's

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourDetach(&(PVOID&)StartDocA_real, StartDocA_hook);

DetourDetach(&(PVOID&)StartDocW_real, StartDocW_hook);

DetourTransactionCommit();

}

return TRUE;

}





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Bob Pooley

We capture the PCL with our port monitor, redirect the spool file to our PCL interpreter and convert to XPS format. We have several ways that the end user can insert text to let our PCL transformation tool know what path/filename is needed. Or, to split the PCL documents into individual XPS files with external indexes for import into document imaging systems, etc. We do the same with PCL when you need to convert to PDF, TIFF or othe formats.

If you are already producing XPS, then all you would need is a port monitor to capture the spool file, rename it and redirect it

For all it's worth..

Regards,

Bob Pooley

www.pagetech.com





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

petersoftware

Thank you for this information about Detours. It looks very interesting and I will take a look. This will take me a few days to brush off my C++ skills as we are developing in VB.Net.

I always get worried when a price is referred to but not shown. It usually means that it will be really expensive.

Does anyone know of a completed non-dialog driver that could use a normal port monitor





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

petersoftware

Thank you for this post. Our original application was written in PCL. One of the reasons for moving to XPS was that sometimes the text in the PCL document was not readable. This was due to the driver adding it as a picture. Ideally I need a solution that goes straight to XPS so that I can read the text out of the Glyph elements.



Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Feng Yue

Microsoft has shipped in Windows Vista WDK a sample XPSDrv driver. After installing the WDK, you can launch the WDK build environment, go to \src\print\XPSDrvSmpl, build it, and then you can install the sample XPSDrv driver from the \src\print\XPSDrvSmpl\install dir. Once you have the sample XPSDrv driver installed, you can set its port to a local file port (for example: c:\temp\test.xps). After that, you can print from any appliation to that sample XPSDrv driver and the output .xps file is in c:\temp\test.xps, without any UI dialog popup.

You can give this a try and see how it fits into your need.

Thanks.

-Feng





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Jo0815

Feng Yue wrote:

Microsoft has shipped in Windows Vista WDK a sample XPSDrv driver. After installing the WDK, you can launch the WDK build environment, go to \src\print\XPSDrvSmpl, build it, and then you can install the sample XPSDrv driver from the \src\print\XPSDrvSmpl\install dir. Once you have the sample XPSDrv driver installed, you can set its port to a local file port (for example: c:\temp\test.xps). After that, you can print from any appliation to that sample XPSDrv driver and the output .xps file is in c:\temp\test.xps, without any UI dialog popup.

You can give this a try and see how it fits into your need.

Thanks.

-Feng




might be a solution if only one client is printing, not when 1-n clients printing simultaneously...
it's probably not the best solution and I also noticed different printing-times when printing to local port, file-port or the traditional way via API (which I have reported months ago to Daniel Emerson and he wanted to get back when they've verified the issue, but I still got no response about) where local port was one of the slower methods...
IMHO Microsoft should support the good old Win32-API function StartDoc() where we were able to set the outputfilename in the DocumentInfo-structure... why isn't that possible




Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

petersoftware

Feng,

Thanks for the note about XPSDrv driver. I have now tried this but get some inconsistent results. Sometimes this driver works completely ok, however other times it appears to hang or crash. This appears to occur on the same files. Also the output XPS file appears to be a lot larger when created by the XPSDrv as apposed to the MXDW.

All,

I am not that up to date on programming drivers and would have thought that Microsoft would be able to package together an official release without the dialog. I am wondering if there is a specific reason not to do this. Perhaps Microsoft are worried about Adobe taking them to court if they make this process seamless If we compile the driver then it would be on our heads This weird thinking would appear to stack up as the dialog could be seen as an explicit authorisation by the user to create an XPS document, thus removing the liability from Microsoft.





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Jo0815

Would be really interesting to know why the Win32-Print-API supports PrintToFile-Option (in the StartDoc() using DocumentInfo-structure) where XPS doesn't support this what is the reason for


Can someone from Microsoft answer this





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Bob Pooley

You can only send a PCL file directly to the printer or use the EscapePassThrough function to get it through a PCL printer driver. Either way, you can only print PCL to a PCL printer. We convert the PCL into a internal Windows device independent bitmap or GDI image, then print it to any Windows device context (printer, screen, etc.). Or, we use our own PDF or XPS drivers (.dll) to output to a file format. If you are still generating PCL, then we can help you. If not, then you're left to whatever has been provided by Microsoft.

Regards,
BP





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

petersoftware

Bob,

Thanks for your posts. I have taken a look at the PageTech main site and also www.pcl2xps.com which I also understand is part of PageTech. My understanding of how this works is a follows.

(1) I install the latest version of PageTech software (currently an evaluation copy).

(2) I then install the PageTech port monitor and create a printer that sents its output to this port monitor.

(3) I configure the port monitor to sent its output to to the PCLXFORM.exe application which outputs an XPS document.

Is this correct I have not got this working yet as I need to look through the documentation, but it looks promising.

I will keep this thread informed of my progress.





Re: XML Paper Specification (XPS) Is There Really No Way To Print XPS From A Generic Application Without Dialog Box?

Bob Pooley

Run PMRemove to startover with the Port Monitor.

Revise items (2/3) - Run PMSetup from our Print Capture Utilities in our program icon group. It will install the PCL Transformation Driver, which prints to our PMon1: port monitor. The Port Monitor redirects the PCL spool file to PCLXForm.exe using the Default.tpt demo script program, which converts the file to PDF. Edit the Default.tpt Conversion=pdfraster to =xpsraster.

I can respond much faster if you email me directly at bp@pagetech.com.

Regards,

Bob Pooley