rodyager / RWTS-PDFwriter

An OSX print to pdf-file printer driver
GNU General Public License v2.0
798 stars 77 forks source link

macOS 14 Sonoma – PDFwriter No Longer Works When Printing from VMware Virtual Machines #44

Closed tree-frog closed 6 months ago

tree-frog commented 10 months ago

Hi Rod,

RWTS-PDFwriter has been an essential tool in my toolbox for many years. Greatly appreciate the work you've put into it.

I use it extensively in combination with virtual machines to generate PDFs on the host system (i.e. RWTS-PDFwriter is installed on the host Mac, and shared as a redirected printer to the virtual machine).

After upgrading to macOS 14 Sonoma, printing from virtual machines no longer works, likely because of Apple's removal of PostScript support. PDFwriter still works just fine locally.

I use VMware Horizon Client to connect to remote sessions, and have posted about the issue on their forum.

"macOS has removed the functionality for converting PostScript and EPS files to PDF format. As a result, CoreGraphics’ CGPSConverter returns an error when invoked, ImageIO no longer converts EPS files, NSEPSImageRep does not display EPS files, and PMPrinterPrintWithFile does not accept a PostScript file for non-PostScript print queues. (110019863)"

With a redirected printer in a remote session initiated with the Horizon Mac Client, printers that do not support the PostScript print queue may not be compatible with the PostScript because the printing data cannot be converted to PDF;

Based on the discussion there, it appears that the printer driver needs to declare itself as accepting a PostScript print queue.

Is this something that RWTS-PDFwriter could support, or is it hopelessly broken after the PostScript changes in macOS 14 Sonoma?

rodyager commented 10 months ago

No. That would not work. Or rather, the effect would be for your document to be saved as a postscript file, which is not what you want.

All PDFWriter does is pretend to be a printer that only understands how to print documents in PDF format. Once given such a document, it saves it to disk rather than actually printing it.

In the past, if the application only knew how to provide the print job in postscript format, the OS converted it to PDF before handing it to PDFWriter. Now, the OS can no longer do this. The OS is still is able to handle other conversions eg bitmap, jpeg, png etc to PDF, so applications that provide their print jobs in these formats still work with PDFWriter.

There is no prospect of adding this capability to PDFWriter. However, it’s likely that many/most applications that used to produce their output in postscript format will be updated to produce their output in another format - as the OS update will mean that the application is incompatible with many physical printers, since postscript is no longer a common document format (due to its inherent security risks)

Rod

Sent from my iPhone

On 26 Oct 2023, at 2:54 pm, tree-frog @.***> wrote:



Hi Rod,

RWTS-PDFwriter has been an essential tool in my toolbox for many years. Greatly appreciate the work you've put into it.

I use it extensively in combination with virtual machines to generate PDFs on the host system (i.e. RWTS-PDFwriter is installed on the host Mac, and shared as a virtual printer to the virtual machine).

After upgrading to macOS 14 Sonoma, printing from virtual machines no longer works, likely because of Apple's removal of PostScript support. PDFwriter still works just fine locally.

I use VMware Horizon Client to connect to remote sessions, and have posted about the issue on their forumhttps://communities.vmware.com/t5/Horizon-Desktops-and-Apps/Virtual-Printers-Not-Working-in-macOS-14-Sonoma-Host-VMware/m-p/2992756/highlight/true#M100108.

"macOS has removed the functionality for converting PostScript and EPS files to PDF format. As a result, CoreGraphics’ CGPSConverter returns an error when invoked, ImageIO no longer converts EPS files, NSEPSImageRep does not display EPS files, and PMPrinterPrintWithFile does not accept a PostScript file for non-PostScript print queues. (110019863)"

With a redirected printer in a remote session initiated with the Horizon Mac Client, printers that do not support the PostScript print queue may not be compatible with the PostScript because the printing data cannot be converted to PDF;

Based on the discussion there, it appears that the printer driver needs to declare itself as accepting a PostScript print queue.

Is this something that RWTS-PDFwriter could support, or is it hopelessly broken after the PostScript changes in macOS 14 Sonoma?

— Reply to this email directly, view it on GitHubhttps://github.com/rodyager/RWTS-PDFwriter/issues/44, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAKSADPRMZPRKPKRA4PYYMLYBHNGNAVCNFSM6AAAAAA6QMUD7GVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE3DENRVGMZTAMY. You are receiving this because you are subscribed to this thread.Message ID: @.***>

tree-frog commented 10 months ago

Thanks very much for the detailed reply. Really appreciate it.

It'll be interesting to see what VMware decides to do with VMware Horizon Client – I see that they removed printer redirection altogether in the release of VMware Fusion 13.5 for Mac last week. Unfortunately, I have no hope that the applications in the virtual machine will be updated, since they're ancient enterprise applications running on Windows.

I may try to see if there's anything similar to PDFwriter that operates on PostScript files like you describe, though that sounds like it would be a fairly niche use case.

Thanks again!

rodyager commented 10 months ago

I have two suggestions that might (or might not) work for you.

The first is to allow PDFWriter to accept postscript source. This would require rebuilding PDFWriter from the source. (Directions are included with the source files).

The modifications you’d need to make are

  1. In build/PDFWriter alter line 19 so that it reads

Filter applicatin/vnd.cups-postscript 0 -

(ie replace the pdf in this line with postscript).

  1. In pdfwriter/main alter line 40 so that it reads

if String(data: prefix, encoding: .utf8)! != “%!PS” {

(ie replace PDF with !PS )

  1. Also in pdfwriter/main alter lines 81 and 85 by replacing .pdf with .ps

This will cause PDFWriter to tell the system it wants postscript files (the effect of the first modification), and it will recognise that this is what it has received (the 2nd modification) and save it for you (with a .ps extension - the effect of the 3rd modification).

But, you probably don’t want postscript files.

The longer shot, but great if it works, is to find a copy of Ventura and copy its /usr/libexec/cups/filter/pstopdffilter to your Sonoma installation. I’ve no idea whether this is enough to allow CUPS to recognise it and use it to convert from postscript to pdf. [Be sure to replicate the same permissions and ownership as the other files in /usr/libexec/cups/filter in your Sonoma installation.]

Let me know how you get on.

Rod

On 26 Oct 2023, at 3:23 pm, tree-frog @.***> wrote:

Thanks very much for the detailed reply. Really appreciate it.

It'll be interesting to see what VMware decides to do with VMware Horizon Client – I see that they removed printer redirection altogether in the release of VMware Fusion 13.5 for Mac last week. Unfortunately, I have no hope that the applications in the virtual machine will be updated, since they're ancient enterprise applications running on Windows.

I may try to see if there's anything similar to PDFwriter that operates on PostScript files like you describe, though that sounds like it would be a fairly niche use case.

Thanks again!

— Reply to this email directly, view it on GitHubhttps://github.com/rodyager/RWTS-PDFwriter/issues/44#issuecomment-1780393286, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAKSADKYFLHBRQR3TXVHMFLYBHQV3AVCNFSM6AAAAAA6QMUD7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTOOBQGM4TGMRYGY. You are receiving this because you commented.Message ID: @.***>

tree-frog commented 10 months ago

Excellent – thanks so much for taking the time to write that up. I will have a look into that in the next couple of weeks to see what is feasible.

If I can even get the PostScript files to work, I should be able to convert them to PDF with e.g. ghostscript or something similar.

d235j commented 7 months ago

Why not bundle GhostScript to do the PS to PDF conversion?

MMeffert commented 6 months ago

Any updates on this issue? Has anyone tried the suggestions from @rodyager and did they work?

tree-frog commented 6 months ago

I tried copying the /usr/libexec/cups/filter/pstopdffilter binary from Ventura to Sonoma. I can confirm that this does not work; Sonoma kills the process when it tries to call the deprecated functions.

VMware Horizon Client version 2312 was released this week with support for third-party postscript-to-PDF conversion using Ghostscript (see https://communities.vmware.com/t5/Horizon-Desktops-and-Apps/Virtual-Printers-Not-Working-in-macOS-14-Sonoma-Host-VMware/m-p/3008120/highlight/true#M100531). Finally.

With the update to VMware Horizon Client, my specific issue is resolved & I haven't come across any other problematic applications. It may be helpful for others to post them here, to see if it's worth modifying RWTS-PDFwriter to integrate with Ghostscript to handle Postscript files.

rodyager commented 6 months ago

Integrating ghostscript into RWTSpdfwriter is almost certainly a non-starter, given the security restrictions Apple places on CUPS backends. The shorter term work around would be to make a trivial modification to the RWTSpdfwriter code to produce a pswriter that causes the MacOS printing system to produce a postscript file in a known location, and then to place a watch action on that folder that notices the postscript file and sends it to Ghostscript to convert it into a pdf file.

Longer term - RWTSpdfwriter is on borrowed time and will cease to work in a future MacOS release. Apple has made it clear that they will not continue to support CUPS backends, and that the future of CUPS is on that requires all printers to run as ipp printers. This means that the way forward is to create an ipp client that responds to CUPS as if it was an ipp printer, but instead of printing, takes the pdf stream (or postscript stream) and saves it to disk. I haven't worked out how to do the first part of that last sentence.

lanec commented 6 months ago

It's sad to see this functionality being depreciated, but given the security overhaul necessary for printer software, these will be rough transitions.

One alternative option for creating a virtual IPP printer on macOS is to use the pyipp library in conjunction with the socket module in Python. Here's a first attempt at a simple IPP print server in Python:

import socket
import select
from pyipp import IPPServer, IPPResponse

def handle_print_job(request):
    # Process the print job here
    print_job = request.document
    print_job_data = print_job.read()
    # Save the print job data to a file or process it further as needed
    with open(f"print_job_{request.job_id}.pdf", "wb") as f:
        f.write(print_job_data)

    # Send a successful response
    response = IPPResponse(version=request.version, status_code='successful-ok')
    return response

def main():
    # Create a socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('localhost', 631))
    server_socket.listen(5)

    print("IPP print server is running on localhost:631")

    while True:
        readable, _, _ = select.select([server_socket], [], [], 1)

        for sock in readable:
            if sock == server_socket:
                # Accept connections
                client_socket, address = server_socket.accept()
                print(f"Connection from {address}")
                # Start IPP server for each connection
                ipp_server = IPPServer(client_socket, handle_print_job)
                ipp_server.handle_requests()

if __name__ == "__main__":
    main()

You can run the script as a background process using the & operator in the command line. For example:

python my_script.py &

tree-frog commented 6 months ago

Integrating ghostscript into RWTSpdfwriter is almost certainly a non-starter, given the security restrictions Apple places on CUPS backends. The shorter term work around would be to make a trivial modification to the RWTSpdfwriter code to produce a pswriter that causes the MacOS printing system to produce a postscript file in a known location, and then to place a watch action on that folder that notices the postscript file and sends it to Ghostscript to convert it into a pdf file.

That's very interesting – thanks for providing your expertise, Rod. The Folder Actions approach sounds very reasonable.

Longer term - RWTSpdfwriter is on borrowed time and will cease to work in a future MacOS release. Apple has made it clear that they will not continue to support CUPS backends, and that the future of CUPS is on that requires all printers to run as ipp printers. This means that the way forward is to create an ipp client that responds to CUPS as if it was an ipp printer, but instead of printing, takes the pdf stream (or postscript stream) and saves it to disk. I haven't worked out how to do the first part of that last sentence.

Also very interesting... I hadn't realized Apple was deprecating CUPS. That's very unfortunate. RWTS-PDFwriter is absolutely essential to my workflow.

One alternative option for creating a virtual IPP printer on macOS is to use the pyipp library in conjunction with the socket module in Python. Here's a first attempt at a simple IPP print server in Python:

That's a neat approach. Thanks for sharing!


I'm going to close this issue, as the specific issue regarding VMware Horizon Client is now resolved. Obviously, the Postscript-apocalypse poses wider problems but these are covered elsewhere.

rodyager commented 6 months ago

They aren’t deprecating CUPS entirely - just removing the functionality on which PDFwriter depends. The deprecation notice has been around for a long time - but so was the notice of the deprecation of postscript!!

Rod

Sent from my iPhone

On 17 Feb 2024, at 4:54 pm, tree-frog @.***> wrote:



Integrating ghostscript into RWTSpdfwriter is almost certainly a non-starter, given the security restrictions Apple places on CUPS backends. The shorter term work around would be to make a trivial modification to the RWTSpdfwriter code to produce a pswriter that causes the MacOS printing system to produce a postscript file in a known location, and then to place a watch action on that folder that notices the postscript file and sends it to Ghostscript to convert it into a pdf file.

That's very interesting – thanks for providing your expertise, Rod. The Folder Actions approach sounds very reasonable.

Longer term - RWTSpdfwriter is on borrowed time and will cease to work in a future MacOS release. Apple has made it clear that they will not continue to support CUPS backends, and that the future of CUPS is on that requires all printers to run as ipp printers. This means that the way forward is to create an ipp client that responds to CUPS as if it was an ipp printer, but instead of printing, takes the pdf stream (or postscript stream) and saves it to disk. I haven't worked out how to do the first part of that last sentence.

Also very interesting... I hadn't realized Apple was deprecating CUPS. That's very unfortunate. RWTS-PDFwriter is absolutely essential to my workflow.

One alternative option for creating a virtual IPP printer on macOS is to use the pyipp library in conjunction with the socket module in Python. Here's a first attempt at a simple IPP print server in Python:

That's a neat approach. Thanks for sharing!


I'm going to close this issue, as the specific issue regarding VMware Horizon Client is now resolved. Obviously, the Postscript-apocalypse poses wider problems but these are covered elsewhere.

— Reply to this email directly, view it on GitHubhttps://github.com/rodyager/RWTS-PDFwriter/issues/44#issuecomment-1949699540, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAKSADPSR4ACH3LEY7NNCTLYUBAYHAVCNFSM6AAAAAA6QMUD7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBZGY4TSNJUGA. You are receiving this because you were mentioned.Message ID: @.***>