Problems automatic printer change

186 views
Skip to first unread message

Peter Vaessen

unread,
Aug 26, 2024, 9:49:21 AM8/26/24
to TheDBCommunity
Had recently already also real issues with this and it got really worse yesterday with constant GPF's under W10. First problem that issued before yesterday was hanging at the first time printersetcurrent() for several PDFCreator printers was used. Workaround was first to make a one time manually print to the PDF printer and after that switching back to paperprinter. After that printersetcurrent() everything went automatic again as long as the Paradox was not restarted againg. This worked OK for let's say around 3-4 months. Since yesterday this workaround did not work anymore. Everytime a GPF, really anoying because this never happened since 1994 to me or other people that are using my software on W7, W8, W10, W11 and even Windows Server. Tried several things (upgrading to W11, downgrading again, deleting last updates, etc, etc). Nothing really worked. Then checked the event log and especially the (event) archive messages under "Mantaince and Security" in the classic small icons Windows Configuration screen. This was the message that made me kind of back on track: 
-------------------------------------------------------- 

A problem caused this program to stop interacting with Windows. Path to :C:\Program Files (x86)\Paradox\Programs\pdxwin32.exe Problem with signature Name of the problemevent: AppHangXProcB1 Application Name: pdxwin32.exe Application Version: 11.0.0.411 Application Timestamp: 42374ed3 Hang Signature: 8eca Hang Type: 134217760 Waiting on Application Name: Microsoft.SharePoint.exe Waiting on Application Version: 24.156.804.2 Version van besturingssysteem: 10.0.19045.2.0.0.256.48 Landinstelling-id: 1043 Additional Hang Signature 1: 8ecaf83ceeecf8c4f6b319bc5775af1a Additional Hang Signature 2: cffd Additional Hang Signature 3: cffd376bddb4f0aa1279cc1cde66f6ff Additional Hang Signature 4: 8eca Additional Hang Signature 5: 8ecaf83ceeecf8c4f6b319bc5775af1a Additional Hang Signature 6: cffd Additional Hang Signature 7: cffd376bddb4f0aa1279cc1cde66f6ff Extra informatie over het probleem Bucket-id: f5ea0214d2fc89936a41e935da55fa53 (1892049735977925203) 
------------------------------------------------ 

 Killed Microsoft.SharePoint.exe 
in Taskmanager and voila, all was working fine again. Hopes this helps some of you to isolate your hangups.  

Steven Green

unread,
Aug 26, 2024, 9:53:34 AM8/26/24
to TheDBCommunity
great detective work !!

Mark Bannister

unread,
Aug 26, 2024, 11:37:07 AM8/26/24
to TheDBCommunity
Had the same problem here last week after and update.  I think we fixed it.  We reset the default printer again.  Word and Excel were choking on printing as well. 

Kevin Zawicki

unread,
Aug 26, 2024, 11:20:15 PM8/26/24
to TheDBCommunity

> Killed Microsoft.SharePoint.exe 

This is fascinating. I have seen this problem appear on PCs since Win7, likely pre Microsoft.SharePoint.exe. I am guessing that is not the only cause.

There are some other refences to OneDrive.

 

After you Killed Microsoft.SharePoint.exe…

…does it return?

…what happens after reboot? 

Tahl Inc

unread,
Aug 30, 2024, 1:15:04 PM8/30/24
to thedbco...@googlegroups.com
I went down the list killing processes until it stopped hanging. One computer it was Fusion 360 cam software causing it, another was one drive. Added it to a bat file to kill the process to make it easier for the user.

Marc
--
You received this message because you are subscribed to the Google Groups "TheDBCommunity" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thedbcommunit...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/thedbcommunity/418cc884-84d9-409b-a63a-cf38bd0cf92an%40googlegroups.com.

Peter Vaessen

unread,
Sep 11, 2024, 2:30:32 PM9/11/24
to TheDBCommunity
It does no return. After reboot you need to kill the process again, but that can be automated

Op dinsdag 27 augustus 2024 om 05:20:15 UTC+2 schreef Kevin Zawicki:

Kevin Zawicki

unread,
Apr 17, 2025, 6:44:16 PMApr 17
to TheDBCommunity

Windows 10, running complex system on standalone PC.

After 10plus years or more...

 

PrinterSetCurrent started hanging last few days. Reboot fixes it. For now.

Again, no real changes.

 

I cannot find anything new or odd running in services.

Microsoft.SharePoint.exe  not running. Fusion 360 cam not running.

I reset paradox default printer and the PC default printer. No change.

I could roll back the latest Win update, it was over a week ago.

 

There is a system created restore point from a few days ago, might revert to that.

 

Ugh. It kills me that these pops up seemingly randomly. In the past the only way to fix was to reinstall windows.

>


Tahl Inc

Aug 30, 2024, 12:15:04 PM

I went down the list killing processes until it stopped hanging. One computer it was Fusion 360 cam
<

Was it hanging (spinning) and as you killed the process it completed? Or did you have to kill a process, then restart Paradox and try again, etc?

  

I may switch to have the PDF printer as the default in Paradox and print to PDF then print the PDF if needed. Anyone done that?

 





On Monday, August 26, 2024 at 8:49:21 AM UTC-5 Peter Vaessen wrote:

Steven Green

unread,
Apr 17, 2025, 6:53:14 PMApr 17
to thedbco...@googlegroups.com

something new must be added to the conflict list, but we must discover it first

Steve at Oasis Trading Post

--
You received this message because you are subscribed to the Google Groups "TheDBCommunity" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thedbcommunit...@googlegroups.com.
Message has been deleted
Message has been deleted

Kevin Zawicki

unread,
Apr 18, 2025, 3:59:58 PMApr 18
to TheDBCommunity

On this PC I have 3-4 users.

Once this problem occurs, it affects other users doing a login or switch to another user. Until reboot.

 

BUT

I also have a hidden user that runs Paradox jobs from the scheduler. When I trigger a job for that user it does not hang. Basically, the hidden user logs in, opens Paradox and runs code, such as making PDFs. One difference is the hidden user (run as other user situation) does not show me the a “screen,” it runs in background, like a service account.

 

I also use AnyDesk and one of the crash logs (only one) listed waiting on AnyDesk. Maybe unrelated.

Kevin Zawicki

unread,
Apr 18, 2025, 3:59:58 PMApr 18
to TheDBCommunity

Bad to worse.

Since yesterday.

I have a few overnight processes that print PDFs (we use Adobe Pro).

These run under the hidden user.

A printing job, about 200 PDFs, failed mid run completing 85 PDFs.

Resetting and manually running the job (so I can watch it), it stops at 85 PDFs each time.

I login in as the hidden user (sometimes the login will be hung at Windows 11 upgrade, I turned that off, but now see a Windows backup reminder screen, bypassed that) and run directly from hidden user. Same issue, but stops at about 81.

The likely eliminates AnyDesk as these run unattended in AM hours and hang.

Then tried running a single job that switches to adobe, prints to file, switches back, fails for all users even after reboot. (Which are what others described, reboot no longer fixes it).

Later I will trace the code (and have base test code) to verify it hangs on printerswitching, BUT my code checks if Paradox printer is already set to Adobe and does not switch if it is already set to Adobe. After each print job I switch back to what the default printer was set to before job. If I change the default printer to Adobe before I start, the PDFs generate faster as it does not have to switch back and forth. (Even If running 100s of PDFs the switching time after each PDF is hardly noticeable). With the default printer set to Adobe, it still hangs.

This leads me to the printersetcurrent is not the problem?  Will trace that later today.

When using Adobe, you preset the PDF name in the registry. This location has changed over the versions, but I have it documented. It seems OK. Since it works “sometimes” I do not think it can be an Adobe setup issue.

I will be checking Windows restore points and maybe updates. Did the basic table damage checks, etc. When this is happening, I watch processes and CPU, there is almost nothing else active.

This kills our PDF making process (even manually). These are synced to multiple PCs and emailed.

Considered changing default printer to Adobe and working it so it then prints hard copy, but as of now Paradox will not print to PDF even interactively if using the automated setup.

I will try manual open to screen printing and other variations later today.

Considering changing to HTML or text-based docs, but you know how customers like change.

 

 

 

 

 

 

 

 

 


On Thursday, April 17, 2025 at 5:53:14 PM UTC-5 Steven Green wrote:

Steven Green

unread,
Apr 18, 2025, 4:07:37 PMApr 18
to thedbco...@googlegroups.com

the problem is printing, not creating, correct? go back to a batch file maybe?

copy my file.pdf \\myserver\myprinter

Steve at Oasis Trading Post

Message has been deleted

Randall Haines

unread,
Apr 18, 2025, 5:46:59 PMApr 18
to TheDBCommunity
Hello Kevin,

We were forced to abandon the use of printerSetCurrent() years ago due to our clients randomly having this GPV issue.
Here is the approach we use instead:
  • Disable the Windows option "Let Windows manage my default printer"  (achieved programmatically through a registry setting). It can interfere with our solution.
  • When Paradox opens:
  • Use Windows API Winspool.dll  GetDefaultPrinterA() and SetDefaultPrinterA() to record the current default printer, then change the default printer to your desired printer (if not default already).
  • Open a report (hidden) that is just a blank page. Close the report. This locks-in the desired printer for the rest of the Paradox session.
  • Use SetDefaultPrinterA() to set the Windows default printer back to what is was (if needed).
  • Paradox's default behavior is to always print to whatever printer was last used, for the rest of the Paradox session.
We use this approach to always print to a certain Xerox Postscript printer that we have installed, then we convert the postscript file to PDF using GhostScript.
If the users want to print to a different printer, they can do it from their PDF reader after we generate our PDF.

Regards,
Randy Haines

Kevin Zawicki

unread,
Apr 19, 2025, 12:50:30 AMApr 19
to TheDBCommunity
The problem is creating.
Still researching.

Kevin Zawicki

unread,
Apr 21, 2025, 12:10:51 AMApr 21
to TheDBCommunity
Well done.
This is a very creative solution. And I have seen MANY.

Kevin Zawicki

unread,
Apr 21, 2025, 12:14:14 AMApr 21
to TheDBCommunity

I tried many things remotely, found nothing.

Every time Paradox hung I rebooted, so almost a reboot after each test.

I found 100s of acrodist.exe tasks (we use acrobat) instances running. They very slowly cleared themselves. Normally during this process, I see them, but they clear quickly to the point of only seeing 2-3 as the press progresses. Odd but still not an explanation. Note I kill task some of the adobe tasks (including this one) after each PDF print having seen these pile up before. It seems they were not being killed. Since a reboot did not correct the problem (a reboot would have cleared all these), I thought it might be a memory capacity issue with acrobat, but again just randomly started a few days ago.

Turned of OneDrive, but it seems to be present around after turn off, so rebooted.
No change to the issue.

I removed the OneNote printer (wish it would never come back removed it in the past.).
No change to the issue, but remember other citing OneNote Printer issues.

Since this issue happened when I was not remoting using AnyDesk, likely not the cause, think I ruled out remote conflict issues.

Next, went in to location (day later).

Intended on using breakpoints / DEBUG() to see it stop hang PrinterSetCurrent().

Ran manual baseline test, single PDF. Ran to success.
Ran unattended baseline test, single PDF. Ran to success.
Ran large batch tests. Ran to success.
Ran multiple combination tests, all to success.

So, it is fixed?

Since it is “fixed itself,” I cannot verify it hung on PrinterSetCurrent() but it seems it did not. It somehow hung on not returning from acrobat, but also not killing that task.

 Maybe OneNote printer / Acrobat conflict issues? Maybe one of the reboots?

Not sure when OneNote printer returned.

There seems to be no update to Windows recently. No update to Acrobat, the version we have is the last Pro version before they went to subscription server (ugh), so no updates ever.

Continuing to monitor, likely not a strict Paradox issue.

Message has been deleted

DIMIM

unread,
Apr 21, 2025, 4:17:02 PMApr 21
to TheDBCommunity
 Hi Kevin / Randy,

To the PrinterSetCurrent poblem:

I use the "deafult" solution and it works - have not the described problems. But if they will appear, I'll give your solution a try (never change a running system).

My "default" solution is:

I've created a ldl-library with my own Print-Method.

All report-names for the app are stored within a table (on each private directory - i.e. for each user) with some additional columns - e.g. how it should be printed - orientation, [here could be set e.g. the X-/Y-Offset too, but this don't work by now] ... and a unique printer-number, which points to an installed printer on the working station, listed within an another table.
The method uses a Report (rep) and a ReportPrintInfo (ri) variables. I use it like this

    Lib.myPrint("myReport")        ; where "myReport" is the Name of the printed report (.RDL file)

The myPrint-Method search within the table for the report name and assign all values to the ReportPrintInfo variable. There's a column, which contains the printer-number, on which the report should be printed (or 0 if on default printer).
The Printer is located within the another Printers table, which contains all installed printers on the workstation.
Rem.: each workstation has it's own printers-table, where all installed printers on this pc ar enumerated (each printer get's [forever] it's own [autoincrement] number). If you uninstall a printer, then it's entry is deleted from the table and all reports going back to the default printer, which is allway used, if none printer number ist set (=0). Therefore there's allways a printer for printing (if at least one is installed).

If the ReportInfo variable ist completed, then I look, which printer is set (be carefull, because Pdox uses only 32 chars to determine the printer name), and if necessary, I'll replace it with:

                                 lp = printerSetCurrent(ar[i])
                                 sleep(1000)
                                 lp = printerSetCurrent(ar[i])
                                 sleep(100)

lp is a logical var. If it's true, then after the print I set back the previous printer.
ar[i] is a field-array with the found printer, which has to be used for the report.
Rem.: the printerSetCurrent ist set two times. Long time ago (many years) I've read something (I think from Liz, but I'm not shure), that it should be called 2x because of a SW-bug. Don't know the details, but I use it since years and it works.

Then I print the report

    rep.print(ri)

and after the print, if lp ist true, I'll set back the previous printer.
Finished.


Here my question. Earlier it was possible to read out / send e-mails with mail. Now it's not.
For printing of some reports I've install the free printer from pdfforge (to create pdf-files, encrypt them and send them as e-mail). It's possible to create my own scripts for printing with needed settings.
What I've not found, is a solution to read out the incoming e-mails (pop and imap). Perhaps there's something to do it.

And a small remark to smb  problem:
There's a dBase SW - is the same situation like pdox (since about 2022 ist's over, but still exists e.g. as FoxPro). Their adventages are. They don't need the BDE anymore (no smb problems), they can use the .net with C# too and they can create exe files (e.g. a way to include pdox).
My idea: I don't know, if it'll by possible to get the pdox code. If yes, then one can ask, if it'll be possible, to stick both (pdox + dbase) together for a LAN database. Later ask for MariaDB (= mySQL) as an enhancement for WAN, internet, ... databases.

Just an idea.

Ivan

Dátum: piatok 18. apríla 2025, čas: 0:44:16 UTC+2, odosielateľ: Kevin Zawicki

Kevin Zawicki

unread,
Apr 21, 2025, 6:08:03 PMApr 21
to TheDBCommunity

>>
My "default" solution is:

I've created a ldl-library with my own Print-Method.    

printerSetCurrent(ar[i])
<< 

Right. I have many routines like this, dynamic printer checks, etc. THIS problem is that printerSetCurrent() hangs. It never returns or errors.

It has been a mystery for many years. 

 

>>>
What I've not found, is a solution to read out the incoming e-mails (pop and imap). Perhaps there's something to do it.
<<

The email object methodology in Paradox no longer functions as it used to function due to Microsoft and Windows changes. Most people found they cannot make it work.

I have moved to third party email programs, there are several (especially for plain text, that allow you to build a config or setup file dynamically and send and receive emails).

I have dedicated library for rolling dynamic batch files or command lines and executing them for many third party tools, email send, email receive, PDF editing, scanning, etc. In one case I built my own emailer in c# and hooked in the EXE.

 

>>>
And a small remark to smb  problem:
There's a dBase SW - is the same situation like pdox (since about 2022 ist's over, but still exists e.g. as FoxPro).

My idea: I don't know, if it'll by possible to get the pdox code. If yes, then one can ask, if it'll be possible, to stick both (pdox + dbase) together for a LAN database. Later ask for MariaDB (= mySQL) as an enhancement for WAN, internet, ... databases.
<<<

Note, so far (anyone) has reported Paradox problems with SMB. I mostly have it on standalone PCs and have not yet seen an issue. Others have more experience, but a few reported no issue with is disabled. Depnds on your setup.

Paradox is still wholly owned and compiled to run in the latest WordPerfect suite, which is certified on the latest Windows OS. There have not been any functional updated in many years. I heard once they had 1-2 support people that only make sure it runs on latest Windows, as it is (only) part of the WordPerfect Suite.  The source code has never been (and unlikely it will ever be) released to public domain or open source.

 

Here, we all recognize this and offer support where possible.

DIMIM

unread,
Apr 22, 2025, 3:27:09 AMApr 22
to TheDBCommunity
Hi Kevin,

> Right. I have many routines like this, dynamic printer checks, etc. THIS problem is that printerSetCurrent() hangs. It never returns or errors.

> It has been a mystery for many years. 


What I remember, there were only problems with printers with names longer than 32 characters. If they were renamed do shorter names, the problem was solved.


> Note, so far (anyone) has reported Paradox problems with SMB. I mostly have it on standalone PCs and have not yet seen an issue. Others have more experience, but a few reported no issue with is disabled. Depnds on your setup.

On a standalone PC you will never see a SMB problem, because SMB has to do with network mapping (i.e. it has nothing to do with the standalone PC, which don't use the network).

Ivan
Dátum: utorok 22. apríla 2025, čas: 0:08:03 UTC+2, odosielateľ: Kevin Zawicki

DIMIM

unread,
Apr 22, 2025, 4:09:28 AMApr 22
to TheDBCommunity
Adding a short info about SMB.

SMB1 uses a not encrypted network-information (and therefore MS want to stop it's usage). Probably within Win12 it can be used, if it's manually installed - will not be installed automatically, but it will be recognized. Later on, SMB1 signature will not be recognized and therefore it can't be used. More details are unknown (perhaps later win-versions can start a virtual box with win7 for older apps - but don't count on it).

Since SMB2 the information is encrypted (this is the main difference). Without code I can't tell, how easy can be to adapt it (but it sounds not to be a big issue). If Corel has 1-2 people for Pdox, I assume, that they can do it within few weeks (the other question, if they want to do it).

Greeting

Ivan

Dátum: utorok 22. apríla 2025, čas: 9:27:09 UTC+2, odosielateľ: DIMIM

Kevin Zawicki

unread,
Apr 22, 2025, 1:05:04 PMApr 22
to TheDBCommunity

>
What I remember, there were only problems with printers with names longer than 32 characters. If they were renamed do shorter names, the problem was solved.
<

That is a long time known issue, but not the problem here.
I have had same printers in place for 10+ years and is suddenly stopped working. This has been reported by many users in past.
In my case there were no significant changes (that I could find), no recent updates to anything.

Kevin Zawicki

unread,
Apr 22, 2025, 1:06:45 PMApr 22
to TheDBCommunity
Basically, Corel wants to do nothing with for Paradox other than keep it alive in the WordPerfect Suite.  They have never even mentioned SMB in the last 20 years that I have seen.

Kevin Zawicki

unread,
Apr 22, 2025, 1:30:53 PMApr 22
to TheDBCommunity

Looks like my long post reply with more details was deleted?

 

 Summary:


The problem has returned after seemingly fixing itself.

 

Researching Randal’s change Windows default printer and open blank report solution, setting the Paradox printer to Adobe, this seems to work, testing.

But it only allows for setting the Paradox printer at first time printing is engaged. Meaning Paradox must “get” the Windows default printer on the first time (blank report) and then hold it as its default in memory? No one has ever found where this is stored.

 

I need to switch on the fly many multiple times without using printerSetCurrent()

Currently my unattended user only uses the PDF printer so it never uses printerSetCurrent().

Interactively I can CTRL-P and manually switch printers if I know a function will print to PDF.

Not the best and killing some canned hit a button processes.

 

Looking at:

 

1)

If I use the blank report to set Paradox default printer to Adobe and always print to PDF, then hard copy print PDFs as needed, that might work, I have all the pieces of code to do that. But a lot of work. Most f the printing sets and code are in a central library.

 

2)

My unattended user works as it only prints to PDF so never uses PrinterSetCurrent(). Its Windows default printer is Adobe.  I might use that as a PDF print device. This unattended user invokes a Paradox library via windows scheduler using a batch file to pass in parameters then makes PDFs. I can call those maybe.

Using another users login to print PDFs.

DIMIM

unread,
Apr 22, 2025, 1:39:32 PMApr 22
to TheDBCommunity
Hi Kevin / Randy,

To the printer-change-problem:


I use the "deafult" solution and it works - have not the described problems. But if they will appear, I'll give your solution a try (never change a running system).

My "default" solution is:

I've created a ldl-library with my own Print-Method.

All report-names for the app are stored within a table with some additional columns - e.g. how it should be printed - orientation, [here could be set e.g. the X-/Y-Offset too, but this don't work by now] ... and a unique printer-number, which points to an installed printer, listed within an another table.
The method uses a Report (rep) and a ReportPrintInfo (ri) variables. I call it like this

    Lib.myPrint("myReport")        ; where "myReport" is the Name of the printed report (= an .RDL file)

The myPrint-Method search within the table for the report name and assign all values to the ReportPrintInfo variable. There' a column, which contains the printer-number, on which the report should be printed (or 0 if on default printer).
The Printer is located within an another Printers table, which contains all installed printers on the working station.
Rem.: each working station has it's own printers-table, where all installed printers on this pc ar enumerated (each printer get's [forever] it's own [autoincrement] number). If you uninstall a printer, then it's entry is deleted from the table and all reports going back to the default printer, which is allway used, if none printer number ist set (=0). Therefore there's allways a printer for printing (if at least one is installed).


If the ReportInfo variable ist completed, then I look, which printer is set (be carefull, because Pdox uses only 32 chars to determine the printer name), and if necessary, I'll replace it with:

                                 lp = printerSetCurrent(ar[i])
                                 sleep(1000)
                                 lp = printerSetCurrent(ar[i])
                                 sleep(100)

lp is a logical var. If it's true, then after the print I set back the previous printer.
ar[i] is a string-array-field with the found printer, which has to be used for the report.
Rem.: the printerSetCurrent ist set two times. Long time ago (many years) I've read something (I think from Liz, but I'm not shure), that it should be called 2 times because of a SW-bug. Don't know the details, but I use it since years and it works.

Then follows the


    rep.print(ri)

and after the print, if lp ist true, I'll set back the previous printer.
Finished.


Here my question. Earlier it was possible to read out / send e-mails with mail. Now it's not.
For printing of some reports I've install the free printer from pdfforge (to create pdf-files, encrypt them and send them as e-mail). It's possible to create my own scripts for printing with needed settings.
What I've not found, is a solution to read out the incoming e-mails (pop and imap). Perhaps there's something to do it.

And a small remark to smb problem:
It exists a dBase SW - is the same situation like pdox (since about 2022 ist's over, but still exists e.g. as FoxPro). Their adventages are. They don't need the BDE anymore (no smb problems), they can use the .net with C# too and they can create exe files (e.g. a way to include pdox).
My idea: I don't know, if it'll by possible to get the pdox code. If yes, then one can ask, if it'll be possible, to stick both (pdox + dbase) together for a LAN database (to use the advantages of both "worlds"). Later ask for MariaDB (= mySQL) as an enhancement for WAN, internet, ... databases.

Just an idea.

Ivan

Dátum: pondelok 21. apríla 2025, čas: 6:14:14 UTC+2, odosielateľ: Kevin Zawicki

Randall Haines

unread,
Apr 22, 2025, 2:31:40 PMApr 22
to TheDBCommunity
Hello Kevin,

>>> 
I need to switch on the fly many multiple times without using printerSetCurrent()
<<<
Sorry, I've spent weeks trying to accomplish that and finally gave up.  I don't think its possible.
A possible alternative solution for you could be to launch another instance of Paradox to print to a different (default) printer instead of calling printerSetCurrent().
Not a clean solution, but it would work and take advantage of using another process thread.
I currently use this solution for other long running processes but not printing.

Randy


Kevin Zawicki

unread,
Apr 22, 2025, 2:43:58 PMApr 22
to TheDBCommunity
Agree.

Can you post the code you use to call the windows dlls to get and set the default printer in windows?

Kevin Zawicki

unread,
Apr 22, 2025, 2:47:04 PMApr 22
to TheDBCommunity
Ivan 
Not sure if you are double posting, or if my posts are getting deleted.
The problem is
printerSetCurrent always hangs, on first try.

Randall Haines

unread,
Apr 22, 2025, 4:04:13 PMApr 22
to TheDBCommunity
The Windows API code was originally obtained from someone else on the old newsgroups probably Pascal Hutton and/or Rick Kelly.
My adaptation is in its own lib "Winspool.lsl"
Yes, we found all the sleeps below to be necessary, especially when working on a customer's slower computer.
The method setPrinterXcm() also checks the printer presence and installs it if needed.  It also sets some registry values to turn off the Windows default printer management feature.
I am posting this code as is, so you will need to purge what you don't want.
We call  setPrinterXcm() from a timer on our main app form. The timer is set from the arrive() of the page at 150 ms.
This is done to let everything finish initializing on the form before setting the printer.
Lib level USES:
Uses "winspool.drv"
  GetDefaultPrinterA(
    stPrinter cptr,
    liBufferSize cptr) cLong [stdcall "GetDefaultPrinterA"]
  SetDefaultPrinterA(
    stPrinter cptr) cLong [stdcall "SetDefaultPrinterA"]
endUses

Uses "user32.dll"
  SendMessageTimeoutA(hWnd cLong,
  msg cLong,
  wParam cLong,
  lParam cLong,
  fuFlags cLong,
  uTimeout cLong,
  lpdwResult cPtr) cLong [stdcall "SendMessageTimeoutA"]
endUses

Uses ObjectPal
ValidateLicenseKey(stLicenseKey String) Logical
W32SetRegistryValue(liRootKey LongInt,
                           stPath String,
                           stValueName String,
                           atValue AnyType,
                           siValueType SmallInt,
                           var liError LongInt) Logical
endUses

The method to set the printer:
;This method exists because we can no longer reliably use the Paradox built-in
;system method priterSetCurrent().  Calling printerSetCurrent() causes Paradox to stop responding.
;When Paradox is started, it does not lock on to a printer and set it as
;the "CURRENT" Paradox printer, until the first report is opened.
;When the first report is opened, Paradox automatically sets the Windows "DEFAULT" printer as
;the Paradox "CURRENT" printer.
;Our strategy is to now only use the HcsTechPDF printer in Paradox.
;To acheive this we:
;1,   Upon opening Paradox, temporarily set the Windows DEFAULT printer to be HcsTechPDF printer
;     using the Windows API methods GetDefaultPrinterA() and SetDefaultPrinter().
;2.   Open and close a blank report.
;3.   Immediately reset the Windows DEFAULT printer back to what it was, using SetDefaultPrinterA()
;     so other programs are not affected by the DEFAULT printer change.
;     Paradox then retains HcsTechPDF as the CURRENT Paradox printer for the life of the session.
method setPrinterXcm()
var
regValAT                AnyType
printerAY               Array[] String ;R01
printersAY              Array[] String ;R01
MainMenuF                 Form           ;R06
registryLIB             Library
wasErrorTrapOnL         Logical
bufLenLI                LongInt
errorLI                 LongInt
resultLI                LongInt
printInfoRec            PrinterInfo ;R05
r                       Report
roi                     ReportOpenInfo
counterSI               SmallInt ; R01
retryCountSI            SmallInt ; R05
tryCountSI              SmallInt ; R04
errorS                  String
error2S                 String
origDefaultApiS         String
origDefaultS            String
printerS                String ;R01
endVar

wasErrorTrapOnL = isErrorTrapOnWarnings()

errorTrapOnWarnings(Yes)

try

   bufLenLI = 256  ;adjust as needed
   origDefaultApiS = space(256)
   printerS = ""
   ;Make sure HcsTechPDF is installed ; begin R01

   enumPrinters(printersAY)
   for counterSI from 1 to printersAY.size()
      printerS = printersAY[counterSI]
      printerS.breakapart(printerAY,",")
      printerS = printerAY[1]

      if printerS = "HcsTechPDF" then
         ;found it
         quitloop
      endIf
   endFor
   if printerS = "HcsTechPDF" then
      ;Continue
   else
       if msgQuestion("Attention",
          "HcsTechPDF printer is not currently installed.\n"+
          "This must be fixed before you can use "+readEnvironmentString("EE44BF65!#.3")+".\n\n"+
          "Installing the HcsTechPDF printer will require \"local administrator\"credentials, and the computer must be restarted after installation.\n\n"+
          "Would you like to attempt to automatically install it now?") = "Yes" then

          writeEnvironmentString("ScriptInputValue", fullname(":SCRIPTS:FixPrinter"))
          if play(":SCRIPTS:LaunchAsAdmin") then
            {msgInfo(
            "Attention",
            "HcsTechPDF printer appears to have been repaired.")}
            fail(
            UserError,
            "RestartPC")
          else
            fail(
            UserError,
            "HcsTechPDF printer was NOT repaired.\n\n"+
            "Please call support for help")
          endIf
       else
         fail(
         UserError,
         "Exit")
       endIf
   endIf ; end R01

   ;R02
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()

   ;Start R03
   try
      ;See if the setting "Let Windows manage my default printer" is on and try turning it off.
       regValAT = getRegistryValue("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", "LegacyDefaultPrinterMode", RegKeyCurrentUser )
       if regValAT = 1 then
          ;Its already off,don't know what else to do.
          ;Nothing
       else
          ;Need errorTrap off for this lib
          errorTrapOnWarnings(No)
          registryLIB.open(":LIBS:PW32REG")
          sleep()
          registryLIB.ValidateLicenseKey("REDACTED")
          errorTrapOnWarnings(Yes)
          registryLIB.W32SetRegistryValue(
                      regKeyCurrentUser,
                      "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
                      "LegacyDefaultPrinterMode",
                      1,
                      0,
                      errorLI)
          sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
          sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
          sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
          sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
       endIf
   onFail
      ;Nothing
   endTry
   ;End R03

   ;Begin R04
   tryCountSI = 0
   try
      tryCountSI = tryCountSI +1
      if GetDefaultPrinterA(origDefaultApiS, bufLenLI) = 1 then
         ; ...success
         ;origDefaultS = origDefaultApiS
         origDefaultS = origDefaultApiS.rtrim()
         origDefaultS = origDefaultS.ltrim()
         if origDefaultS = "" then ; begin R01
            fail(
            UserError,
            "WinSpool.lsl setPrinterXcm() Could not get the windows default printer using Windows API method GetCurrentPrinter(),\n"+
            "Default printer name is blank")
         else
            ;Continue
         endIf ;end R01

      else
         ; ...show an error message
         fail(
         UserError,
         "WinSpool.lsl setPrinterXcm() Could not get the windows default printer using Windows API method GetCurrentPrinter()")
      endIf
   onFail
      if tryCountSI = 4 then
         fail(
         UserError,
         errorMessage())
      else
         errorClear()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep(2000)
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         retry
      endIf

   endTry

   ;Begin R05
   retryCountSI = 0
   try
      retryCountSI = retryCountSI +1
      if origDefaultS = "HcsTechPDF" then
         ;Correct printer already set to Windows default
      else
         if SetDefaultPrinterA("HcsTechPDF") = 1  then
            ;resetPrinterL = True ;begin R01
            sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
            ; Send out alert to all running applications
            ; that a system value has been updated
            SendMessageTimeoutA(-1,
            26,
            0,
            0,
            0,
            100,
            resultLI)
            ;end R01
            sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()
            sleep(100)sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()
            sleep()sleep()sleep()sleep()sleep()sleep()
         else
            fail(
            UserError,
            "WinSpool.lsl setPrinterXcm() Could not temporarily set windows default printer to HcsTechPDF using Windows API SetDefaultPrinterA().\n"+
            "Please call support for help.")
         endIf
      endIf
      ;End R04

      sleep()

      roi.name         = ":REPORTS:BLANK"
      roi.winStyle       = WinStyleDefault+WinStyleHidden
      sleep()sleep()sleep()sleep()sleep(10)sleep()sleep()sleep()sleep()sleep()   ;R06
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep(10)sleep()sleep()sleep()sleep()sleep()   ;R06

      r.open(roi)
      sleep()sleep()sleep()sleep()sleep(10)sleep()sleep()sleep()sleep()sleep()   ;R06
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()

      if r.isAssigned() then
         r.close()
      endIf

      ;R02
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
      sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()

       ;See if the Paradox active printer is now correct
      printerGetInfo(printInfoRec)  ;NOTE calling thi method also seems lock-in the printer on Paradox so no use retrying ;R06
      if printInfoRec.DEVICENAME = "HcsTechPDF" then
         ;correct
      else
        
         fail(
         UserError,
         "WinSpool.lsl setPrinterXcm() Could not set printer to HcsTechPDF.\n"+
         "Please close "+readEnvironmentString("EE44BF65!#.3")+" completely and open it again, or restart your computer, and try again")
      endIf

      printInfoRec.DEVICENAME = blank()
   onFail
      if retryCountSI = 1 then ;try 1 time
      ;start ;R06
         error2S = errorMessage()
        
         errorTrapOnWarnings(No)
         if MainMenuF.attach("MainMenu") then

            MainMenuF.unAssign()
            errorTrapOnWarnings(Yes)

            fail(
            UserError,
            error2S)

         else
            errorTrapOnWarnings(Yes)
            errorClear()
         endIf
        ;end ; R06
      else
         errorClear()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         ;R06 sleep(2000)
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         retry
      endIf

   endTry

   ;End R05

   ;In all cases reset the default printer back to what it was, if it was changed
   ;if resetPrinterL = True then ; begin R01
   if origDefaultS <> "HcsTechPDF" AND origDefaultS <> "" then
      if SetDefaultPrinterA(origDefaultApiS) = 1  then
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         ; Send out alert to all running applications
         ; that a system value has been updated
         SendMessageTimeoutA(-1,
         26,
         0,
         0,
         0,
         100,
         resultLI)
         ;end R01
         sleep()sleep()sleep()sleep()sleep()sleep()
      else
         ; ...show an error message
         ; R01
         fail(
         UserError,
         "Could not reset your default printer back to "+origDefaultS+".\n\n"+
         "Please call support for help.") ;R01
      endIf
   else
      ; ...don't reset
      ;Default printer is HcsTechPDF
   endIf

   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
   sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()

onFail

   errorS = errorMessage()
   if errorS = "RestartPC" then
      fail(
      UserError,
      "RestartPC")
   else
      if errorS = "Exit" then
         ;Nothing
      else
         errorShow()
         ;R02
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep(10)sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         sleep()sleep()sleep()sleep()sleep()sleep()sleep()sleep()
         ;In all other cases reset the default printer back to what it was, if it was changed
         ;if resetPrinterL = True then ;begin R01
         if origDefaultS <> "HcsTechPDF" AND origDefaultS <> "" then
            if SetDefaultPrinterA(origDefaultApiS) = 1  then
               sleep()sleep()sleep()sleep()sleep()sleep()
               ; Send out alert to all running applications
               ; that a system value has been updated)
               SendMessageTimeoutA(-1,
               26,
               0,
               0,
               0,
               100,
               resultLI)
               ;end R01
               sleep()sleep()sleep()sleep()sleep()sleep()
            else
                ; ...show an error message
                ;MsgBox('Warning - Could not set your default printer to HcsTechPDF.', mbInformation, MB_OK);
            endIf
         else
            ; ...don't reset
         endIf
      endIf
      fail(
      UserError,
      "Exit")
   endIf

endTry

if registryLIB.isAssigned() then
   registryLIB.close()
   sleep()
endIf

errorTrapOnWarnings(wasErrorTrapOnL)
endMethod

Kevin Zawicki

unread,
Apr 23, 2025, 3:26:06 PMApr 23
to TheDBCommunity
PrinterSetCurrent() update
The premise is that PrinterSetCurrent() seemingly randomly and inconsistency hangs.
Thanks to all for the posts and ideas in group and out of group.
Remember the problem is I cannot use PrinterSetCurrent(), even once, it might hang.

The change printer issue occurred again, seemingly randomly after not occurring for days.
Problem returned on main interactive user, randomly.
This time I could trace the code and verified it is PrinterSetCurrent().

While hung up, I ran a hidden user unattended process, IT RAN TO SUCCESS. But in the unattended user the windows default printer is permanently set to Adobe and my printer switcher code checks if a switch is needed, and since it is never needed on this user PrinterSetCurrent() is never used. Further evidence it is PrinterSetCurrent().

Paradox “reads in” the Windows default printer at open then holds it for the session.

Randall Haines’s solution opens a blank report and saves. Randall, what does that do? Isn’t the default Paradox printer already set on open of Paradox?

If I cannot switch dynamically, I need to set the Paradox printer to Adobe and always print to Adobe, then print hard copy from PDF. (Some of you do this and suggested this and this was always my plan B.)
If I need to set the Paradox default printer to NOT the Windows default printer, I must change the Windows default printer to what I need, before I open Paradox. There are many ways do this (some of you posted), even command lines.
This is interesting...   command lines set the default printer.

wmic printer get name,default (shows them all)
and
wmic printer where name="Microsoft Print to PDF" call setdefaultprinter

The idea is using whatever way to set the Windows default printer, start Paradox, change Windows default printer to what it was originally. Once I do that, I must modify all the hard copy print places to print the PDF if needed.

Most the print jobs are sent to one library method and handled there. Some of my large report sets runs print reports to PDF and hardcopy, going back and forth for 100s of reports. I had thought of changing it to making all the PDFs, then just printing the PDFs, more efficient, and that is where I am ending up.


Option 2
Building a PDF “printer server” routine on the unattended user and having it make the PDFs, somehow invoking a Windows task scheduler job on the fly. The unattended user jobs already run in a separate library from Windows task scheduler. I may use a batch job for the ad hoc ones. This would work, but a complicated series of setups the unattended always looking for a trigger to engage.

Kevin Zawicki

unread,
Apr 23, 2025, 3:47:34 PMApr 23
to TheDBCommunity

> Paradox “reads in” the Windows default printer at open then holds it for the session.
So this is not actually true, it reads at time of first print.

> Randall Haines’s solution opens a blank report and saves. Randall, what does that do? Isn’t the default Paradox printer already set on open of Paradox?
Paradox only reads the Windows default printer WHEN first printing is engaged and then holds it. In memory (I guess).

> The idea is using whatever way to set the Windows default printer, start Paradox, change Windows default printer to what it was originally. Once I do that, I must modify all the hard copy print places to print the PDF if needed.
But really 
The idea is using whatever way to set the Windows default printer, start Paradox, print or engage printing to hold that, THEN change Windows default printer to what it was originally.


Randall Haines

unread,
Apr 23, 2025, 5:25:17 PMApr 23
to TheDBCommunity
Kevin,
Your conclusions are correct.  

>Paradox only reads the Windows default printer WHEN first printing is engaged and then holds it. In memory (I guess).
>The idea is using whatever way to set the Windows default printer, start Paradox, print or engage printing to hold that, THEN change Windows default printer to what it was originally.

Yes as far as I can tell it is held in memory by Paradox. The default Windows default printer is locked into Paradox memory when the first report is opened r.open(roi).  Printing is not required.

Randy

Steven Green

unread,
Apr 23, 2025, 5:35:12 PMApr 23
to thedbco...@googlegroups.com

interesting discussion.. only thing I'll add is AFAIK "all printers" to memory, not just the default.. that's how the "ghost printer" GP happens

Steve at Oasis Trading Post

Kevin Zawicki

unread,
Apr 24, 2025, 9:28:12 PMApr 24
to TheDBCommunity
printerSetCurrent() workaround
Since printerSetCurrent() can fail and hang I am changing my application to always use Adobe PDF printer and will hard copy print PDFs in code if needed.

This eliminates the need for printerSetCurrent(), but adds the slight complexity of printing to a temp PDF and hard copy printing that to the Windows default printer. I already have a PDF library and a few third-party tools to print PDFs, command line prints, etc., just have to rework the flow.

Since I always will set Paradox to the same Adobe printer, and we always have one HP printer set to default printer for all users I did not need (yet) to store the current default printer name.
I believe if needed it you can use printerGetCurrent() without problems. You can vary this as needed with variables, user settings, etc.

I set the Paradox default printer in the main start up script for the application, and always start the application with a set working directory at the command line.

Here is a “lite” version of what I am doing. Have not added error trapping yet.

;//library method
method setWindowsDefaultPrinter(p string)
 var
  exe string
 endvar

 ;//this commandline seems much simpler than call DLLs
 exe = "wmic printer where name=\"" + p + "\" call setdefaultprinter"
 execute(exe,true, ExeHidden)
endMethod


start script snippet:
var
 rp report
 winlib library
endvar

winLib.open(":WORK:win")

;// set windows default printer so paradox takes it then set back
winLib.SetWindowsDefaultPrinter("Adobe PDF")   ;// can be a variable we have a static name

;//may use printerGetCurrent() to validate

;// do “print engage” to lock in for session, any report works, this is a shell blank one, simple
rp.open(":WORK:printerLock",winstylehidden)
rp.close()

;//set it back
winLib.SetWindowsDefaultPrinter("Office 477") ;// can be a variable we have a static name

;//may use printerGetCurrent() to validate


winLib.close()

If you open windows Printers and Scanners and step through the code you can see it change there live.


Comments
Thanks for all the input.

Was mentioned that best to turn off “Let Windows manage my default printer” ...  I have all users set to do that on login.

It seems clear Paradox “reads in” all installed printers and the windows default printer, then uses the windows default as its default for rest of session at the time of engaging printing. Not actually printing, just opening a report to screen accomplishes the setting.

If only they had included a [PrinterDestination] element in the ReportPrintInfo array…?



Has anyone used:
printToFile
If blank, the report is sent to the printer. Otherwise, the printer instructions are placed in the specified file on disk rather than being sent to the printer. Defaults to Blank.

Is this file a PS file?
Can it be send to any printer via commandline?

Randall Haines

unread,
Apr 25, 2025, 12:43:47 PMApr 25
to TheDBCommunity
Hi Kevin,

I have not used PrintToFile.  It appears to be the same as interactively setting a "FILE:" port type in Windows printer properties dialog. However I understand it may prompt the user for a file name.
You can print to a file (same name and path always), simply by creating a new printer port of "local type" and entering a full path to the file as the name of the port (like c:\temp\MyPrintJob.ps).  The kind of file generated depends on the printer driver used   A postscript driver creates postscript file, PCL drive creates PCL file.  However it will be named whatever name you put as the local port name.

I don't use WMIC because it may go away at some point since it is deprecated by Microsoft: https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmic

Randy

Kevin Zawicki

unread,
Apr 25, 2025, 3:06:19 PMApr 25
to TheDBCommunity

I don't use WMIC because it may go away at some point since it is deprecated by Microsoft: https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmic

This utility is superseded by Windows PowerShell for WMI

….

Right, this was the fastest solution for me, but I wrapped it in a library method so I can just update that one method if needed. There are many ways to do this.

“superseded,” ha, Like Windows 10, Paradox, the version of MS-Office we have, probably 5-6 third party utilities, etc. but point taken.

 

The key was really the report open and close to lock it in.

Reply all
Reply to author
Forward
0 new messages