How to use Python win32print to change Printer trays - python

I am using Windows 10 and MS PCL6 Class Driver on a SHARP MX-M654N printer. I can successfully print a PDF file to the printer but I need to print every third page of the PDF to a different tray (different paper color).
The following code returns pywintypes.error: (5, 'OpenPrinter', 'Access is denied.') I have also tried ADMINISTER in place of PRINTER_ALL_ACCESS with the same result.
# PRINTER_DEFAULTS = {"DesiredAccess":win32print.PRINTER_ALL_ACCESS}
# pHandle = win32print.OpenPrinter(printer_name, PRINTER_DEFAULTS)
I have also tried the following without using the above but command is ignored
# win32print.SetJob(ph, hJob, 0, None, tray1_name)

Related

Why do I only get the Desktop wallpaper when trying to take a screenshot on a Mac?

I'm trying to take a screenshot with python. But every option I try only seems to return the desktop wallpaper and not the programs on top.
Here's a run through of what I've tried and how I'm doing it.
First I used autopy to try and get pixels from the screen using autopy.color.hex_to_rgb(autopy.screen.get_color(x, y)). But it was only telling me the pixels of the desktop background.
Then I tried PIL(Pillow) using this code:
from PIL import ImageGrab
im = ImageGrab.grab()
im.save('screenshot.png')
This only returned the desktop wallpaper.
Finally, I've tried using this script which I found on this thread.
import Quartz
import LaunchServices
from Cocoa import NSURL
import Quartz.CoreGraphics as CG
def screenshot(path, region = None):
"""region should be a CGRect, something like:
>>> import Quartz.CoreGraphics as CG
>>> region = CG.CGRectMake(0, 0, 100, 100)
>>> sp = ScreenPixel()
>>> sp.capture(region=region)
The default region is CG.CGRectInfinite (captures the full screen)
"""
if region is None:
region = CG.CGRectInfinite
# Create screenshot as CGImage
image = CG.CGWindowListCreateImage(
region,
CG.kCGWindowListOptionOnScreenOnly,
CG.kCGNullWindowID,
CG.kCGWindowImageDefault)
dpi = 72 # FIXME: Should query this from somewhere, e.g for retina displays
url = NSURL.fileURLWithPath_(path)
dest = Quartz.CGImageDestinationCreateWithURL(
url,
LaunchServices.kUTTypePNG, # file type
1, # 1 image in file
None
)
properties = {
Quartz.kCGImagePropertyDPIWidth: dpi,
Quartz.kCGImagePropertyDPIHeight: dpi,
}
# Add the image to the destination, characterizing the image with
# the properties dictionary.
Quartz.CGImageDestinationAddImage(dest, image, properties)
# When all the images (only 1 in this example) are added to the destination,
# finalize the CGImageDestination object.
Quartz.CGImageDestinationFinalize(dest)
if __name__ == '__main__':
# Capture full screen
screenshot("/tmp/testscreenshot_full.png")
# Capture region (100x100 box from top-left)
region = CG.CGRectMake(0, 0, 100, 100)
screenshot("/tmp/testscreenshot_partial.png", region=region)
Again it returns my desktop wallpaper.
Why is it doing this? How can I get a screenshot in the same way I would if I were to press 'cmd + shift + 3'.
This is a privacy feature, macOS prevents arbitrary apps from viewing the contents of other app windows. To get permission, your app will need access to the screen recording permission in macOS preferences.
Since this is a Python script, I think the app you're running the script from needs to be given permission, so either Terminal or whatever IDE you're using.

Sending keyboard input to Notepad++ via windows api in Python

I'm aware of the fact that not all windows process keyboard input. However, ONE of the windows of my Notepad++ tree should have an effect on the editor, i.e. write the 'A' that I'm trying to send. I have tried all child windows but nothing works:
def mycallback(hwnd, data):
data[hwnd] = win32gui.GetClassName(hwnd)
win32gui.EnumChildWindows(hwnd, mycallback, data)
return True
mywindows = {}
win32gui.EnumChildWindows(197788, mycallback, mywindows) # 197788 is the notepad++ handle whose parent is 0
# at this point, mywindows contains: {'#32770': 66908, 'Button': 66922, 'Static': 66924, 'SysTabControl32': 132272, 'Scintilla': 132276, 'splitterContainer': 263444, 'wespliter': 328982, 'msctls_statusbar32': 394476, 'dockingManager': 394474, 'wedockspliter': 132328, 'nsdockspliter': 132336, 'ReBarWindow32': 66906, 'ToolbarWindow32': 66902, 'Edit': 66914}
for v in mywindows.values():
win32api.SendMessage(v, win32con.WM_CHAR, 0x41, 0) # trying to send an 'A' to notepad++ without knowing to which window I need to send it to. I had already noticed before that sending the 'A' to the "Edit" window doesn't work (the EXACT same win32api.SendMessage command works for the "Edit" window of the Microsoft-Windows-notepad-editor by the way)
# the return values of this loop are: 0,0,0,0,0,0,0,0,0,0,0,0,0,1
Only the "Edit" window returns 1. And 1 means error, so I'm assuming "Edit" is the right window to target but why does it return error?
And by the way: the "Edit" window of the Microsoft-Windows-notepad-editor also returns 1, but it prints the 'A' to the editor.

How to suppress the "Microsoft PDF Reflow has stopped working" error when using python to open pdf file with MS Word?

I was trying to automate the pdf-to-docx process using python.
PDF Reflow will automatically opened if I open pdf files with MS Word. Therefore, I used it as an OCR tool.
I have suppressed the message boxes from Word by using word_app.DisplayAlerts=0 and try-except.
However, message box "Microsoft PDF Reflow has stopped working" still popped out sometimes.
Now I should manually close those message boxes and it is not reasonable for an automated process. Is there anyway to suppress the errors from PDF Reflow?
Below is the code I use:
import pythoncom
import win32com
from win32com.client import Dispatch, constants
#import logging
word_app = win32com.client.gencache.EnsureDispatch("Word.Application")
word_app.Visible = 0
word_app.DisplayAlerts = 0
wc = win32com.client.constants
try:
word_doc = word_app.Documents.Open('file.pdf')
except pythoncom.com_error as e:
print(e)
#logger.info(e)
word_doc.SaveAs(FileName = 'file.docx', FileFormat = wc.wdFormatXMLDocument)
word_doc.Close(SaveChanges = wc.wdDoNotSaveChanges)
word_app.Quit()
Thank you for any help!
Found answer by myself:
import win32com
shell_app = win32com.client.Dispatch('WScript.Shell')
RegKey = r'HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting'
GetKeyValue = shell_app.RegRead(os.path.join(RegKey, "DontShowUI"))
EditKeyValue = shell_app.RegWrite(os.path.join(RegKey, "DontShowUI"), 1, "REG_DWORD")
##use this to restore your registry
RestoreKeyValue = shell_app.RegWrite(os.path.join(RegKey, "DontShowUI"), GetKeyValue, "REG_DWORD")
Be careful when using this code because it edits registry and may damage your computer.
This code is not an ideal solution as it will suppress not only PDF Reflow's error reporting but ALL of them.

Selenium python interact with FileOpen window

From Selenium, I managed to automate my tasks for a website.
However I ran into a problem:I need to upload a file to my web-page before submitting the form.
It is NOT an option to write the uploaded file into it's input element, because it is more complicated than this.
So basically I need to launch the FileUpload dialog by clicking a button, sendKeys there, and then close it by clicking on Ok.
I am wondering if this is even possible using just Selenium?
I am using it from python (so I don't have access to Robot class)
I tried so far:
element.click()
time.sleep(5)
alert = driver.switch_to.alert
alert.send_keys("path.to.myfile.txt")
alert.accept()
(nothing happens - I mean, the file open dialog works fine, but it does not send the keys )
I also tried:
alert = driver.switch_to.alert
buildu = ActionChains(driver).send_keys('path.to.my.file.txt')
buildu.perform()
(also not working)
Maybe I am looking at it wrong...
Maybe the alerts is not a good approach?
Do you have any idea?
I would prefere not having to use AUTOIT (for my own reasons)
So my goal is to click on a link element (DONE) then the link opens the File Upload open file dialog (DONE), then I need to be able to enter a text in the only textBox of the new window, and click on the Ok button
EDIT
This is the Open File dialog that shows up.
All I want to do is send the filename directly to the window (the textBox is focused when the dialog shows up, so no need to make more actions). After I send the keys (text) I need to be able to click on the Open button
You can create a Java program that will paste the filename and press the enter key. I had this same problem exactly. This is how I implemented:
package myaots_basic;
import java.io.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
public class trial {
public static void main(String[] args) throws AWTException {
System.out.println("HELLO WORLD");
StringSelection attach1 = new StringSelection ("C:\\My Office Documents\\Selinium projects\\Data\\attachment1.doc");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(attach1, null);
Robot rb1 = new Robot();
rb1.delay(3000);
rb1.keyPress(KeyEvent.VK_CONTROL);
rb1.keyPress(KeyEvent.VK_V);
rb1.keyRelease(KeyEvent.VK_V);
rb1.keyRelease(KeyEvent.VK_CONTROL);
rb1.delay(500);
rb1.keyPress(KeyEvent.VK_ENTER); // press Enter
rb1.keyRelease(KeyEvent.VK_ENTER);
}
}
Name it to trial.jar. Make this class a an executable.
Then in your python code just add a simple step:
import subprocess
subprocess.call("java -jar trial.jar", shell=True)
I don't know if this is restricted to windows 10 or works slightly different in other Windows versions but you can use the following code/idea.
Open the windows shell with win32com.client.Dispatch("WScript.Shell")
Send Tab keys to navigate through the open file dialog
Paste your absolute file path into the top of the dialog and also into the file selection text field and send enter key when
tab-navigating to the "open" button
Make a sleep of at least 1 second between each action.. otherwise Windows blocks this action.
import win32com.client as comclt
...
def handle_upload_file_dialog(self, file_path):
sleep = 1
windowsShell = comclt.Dispatch("WScript.Shell")
time.sleep(sleep)
windowsShell.SendKeys("{TAB}{TAB}{TAB}{TAB}{TAB}")
time.sleep(sleep)
windowsShell.SendKeys("{ENTER}")
time.sleep(sleep)
windowsShell.SendKeys(file_path)
time.sleep(sleep)
windowsShell.SendKeys("{TAB}{TAB}{TAB}{TAB}{TAB}")
time.sleep(sleep)
windowsShell.SendKeys(file_path)
time.sleep(sleep)
windowsShell.SendKeys("{TAB}{TAB}")
time.sleep(sleep)
windowsShell.SendKeys("{ENTER}")
...

Pipsta Printer and Printing a list

I'm trying to modify the simple python script provided with my Pipsta Printer so that instead of printing a single line of text, it prints out a list of things.
I know there are probably better ways to do this, but using the script below, could somebody please tell me what changes I need to make around the "txt = " part of the script, so that I can print out a list of items and not just one item?
Thanks.
# BasicPrint.py
# Copyright (c) 2014 Able Systems Limited. All rights reserved.
'''This simple code example is provided as-is, and is for demonstration
purposes only. Able Systems takes no responsibility for any system
implementations based on this code.
This very simple python script establishes USB communication with the Pipsta
printer sends a simple text string to the printer.
Copyright (c) 2014 Able Systems Limited. All rights reserved.
'''
import argparse
import platform
import sys
import time
import usb.core
import usb.util
FEED_PAST_CUTTER = b'\n' * 5
USB_BUSY = 66
# NOTE: The following section establishes communication to the Pipsta printer
# via USB. YOU DO NOT NEED TO UNDERSTAND THIS SECTION TO PROGRESS WITH THE
# TUTORIALS! ALTERING THIS SECTION IN ANY WAY CAN CAUSE A FAILURE TO COMMUNICATE
# WITH THE PIPSTA. If you are interested in learning about what is happening
# herein, please look at the following references:
#
# PyUSB: http://sourceforge.net/apps/trac/pyusb/
# ...which is a wrapper for...
# LibUSB: http://www.libusb.org/
#
# For full help on PyUSB, at the IDLE prompt, type:
# >>> import usb
# >>> help(usb)
# 'Deeper' help can be trawled by (e.g.):
# >>> help(usb.core)
#
# or at the Linux prompt, type:
# pydoc usb
# pydoc usb.core
PIPSTA_USB_VENDOR_ID = 0x0483
PIPSTA_USB_PRODUCT_ID = 0xA053
def parse_arguments():
'''Parse the arguments passed to the script looking for a font file name
and a text string to print. If either are mssing defaults are used.
'''
txt = 'Hello World from Pipsta!'
parser = argparse.ArgumentParser()
parser.add_argument('text', help='the text to print',
nargs='*', default=txt.split())
args = parser.parse_args()
return ' '.join(args.text)
def main():
"""The main loop of the application. Wrapping the code in a function
prevents it being executed when various tools import the code.
"""
if platform.system() != 'Linux':
sys.exit('This script has only been written for Linux')
# Find the Pipsta's specific Vendor ID and Product ID
dev = usb.core.find(idVendor=PIPSTA_USB_VENDOR_ID,
idProduct=PIPSTA_USB_PRODUCT_ID)
if dev is None: # if no such device is connected...
raise IOError('Printer not found') # ...report error
try:
# Linux requires USB devices to be reset before configuring, may not be
# required on other operating systems.
dev.reset()
# Initialisation. Passing no arguments sets the configuration to the
# currently active configuration.
dev.set_configuration()
except usb.core.USBError as ex:
raise IOError('Failed to configure the printer', ex)
# The following steps get an 'Endpoint instance'. It uses
# PyUSB's versatile find_descriptor functionality to claim
# the interface and get a handle to the endpoint
# An introduction to this (forming the basis of the code below)
# can be found at:
cfg = dev.get_active_configuration() # Get a handle to the active interface
interface_number = cfg[(0, 0)].bInterfaceNumber
# added to silence Linux complaint about unclaimed interface, it should be
# release automatically
usb.util.claim_interface(dev, interface_number)
alternate_setting = usb.control.get_interface(dev, interface_number)
interface = usb.util.find_descriptor(
cfg, bInterfaceNumber=interface_number,
bAlternateSetting=alternate_setting)
usb_endpoint = usb.util.find_descriptor(
interface,
custom_match=lambda e:
usb.util.endpoint_direction(e.bEndpointAddress) ==
usb.util.ENDPOINT_OUT
)
if usb_endpoint is None: # check we have a real endpoint handle
raise IOError("Could not find an endpoint to print to")
# Now that the USB endpoint is open, we can start to send data to the
# printer.
# The following opens the text_file, by using the 'with' statemnent there is
# no need to close the text_file manually. This method ensures that the
# close is called in all situation (including unhandled exceptions).
txt = parse_arguments()
usb_endpoint.write(b'\x1b!\x00')
# Print a char at a time and check the printers buffer isn't full
for x in txt:
usb_endpoint.write(x) # write all the data to the USB OUT endpoint
res = dev.ctrl_transfer(0xC0, 0x0E, 0x020E, 0, 2)
while res[0] == USB_BUSY:
time.sleep(0.01)
res = dev.ctrl_transfer(0xC0, 0x0E, 0x020E, 0, 2)
usb_endpoint.write(FEED_PAST_CUTTER)
usb.util.dispose_resources(dev)
# Ensure that BasicPrint is ran in a stand-alone fashion (as intended) and not
# imported as a module. Prevents accidental execution of code.
if __name__ == '__main__':
main()
Pipsta uses linux line-feed ('\n', 0x0A, 10 in decimal) to mark a new line. For a quick test change BasicPrint.py as follows:
#txt = parse_arguments()
txt = 'Recipt:\n========\n1. food 1 - 100$\n2. drink 1 - 200$\n\n\n\n\n'
usb_endpoint.write(b'\x1b!\x00')
for x in txt:
usb_endpoint.write(x)
res = dev.ctrl_transfer(0xC0, 0x0E, 0x020E, 0, 2)
while res[0] == USB_BUSY:
time.sleep(0.01)
res = dev.ctrl_transfer(0xC0, 0x0E, 0x020E, 0, 2)
I commented out parameter parsing and injected a test string with multi line content.

Categories