How to determine if win32api.ShellExecute was successful using hinstance?

守給你的承諾、 提交于 2020-03-18 06:40:14

问题


I've been looking around for an answer to my original issue.. how do i determine (programmatically) that my win32api.ShellExecute statement executed successfully, and if a successful execution occurs, execute an os.remove() statement.

Researching I found out that the ShellExecute() call returns the HINSTANCE. Further digging I found that ShellExecute() will return an HINSTANCE > 32 if it was successful. My problem/question now is, how do i use it to control the rest of my program's flow? I tried using an if HINSTANCE> 32: statement to control the next part, but I get a NameError: name 'hinstance' is not defined message. Normally this wouldn't confuse me because it means i need to define the variable 'hinstance' before referencing it; however, because i thought ShellExecute is supposed to return HINSTANCE, i thought that makes it available for use?

Here is my full code where i am trying to implement this. Note that in my print_file() def i am assigning hinstance to the full win32api.ShellExecute() command in attempt to capture the hinstance along with explicitly returning it at the end of the function.. this isn't working either.

import win32print
import win32api
from os.path import isfile, join
import glob
import os
import time

source_path = "c:\\temp\\source\\"

def main():
    printer_name = win32print.GetDefaultPrinter()
    while True:
        file_queue = [f for f in glob.glob("%s\\*.txt" % source_path) if isfile(f)]
        if len(file_queue) > 0:
            for i in file_queue:
                print_file(i, printer_name)
                if hinstance > 32:
                    time.sleep(.25)
                    delete_file(i)
                print "Filename: %r has printed" % i
                print
                time.sleep(.25)
                print                
        else:
            print "No files to print. Will retry in 15 seconds"
        time.sleep(15)


def print_file(pfile, printer):
    hinstance = win32api.ShellExecute(
        0,
        "print",
        '%s' % pfile,
        '/d:"%s"' % printer,
        ".",
        0
        )
    return hinstance


def delete_file(f):
    os.remove(f)
    print f, "was deleted!"

def alert(email):
    pass

main()

回答1:


With ShellExecute, you will never know when the printing is complete, it depends on the size of the file and whether the printer driver buffers the contents (the printer might be waiting for you to fill the paper tray, for example).

According to this SO answer, it looks like subprocess.call() is a better solution, since it waits for the command to complete, only in this case you would need to read the registry to obtain the exe associated with the file.

ShellExecuteEx is available from pywin32, you can do something like:

import win32com.shell.shell as shell
param = '/d:"%s"' % printer
shell.ShellExecuteEx(fmask = win32com.shell.shellcon.SEE_MASK_NOASYNC, lpVerb='print', lpFile=pfile, lpParameters=param)

EDIT: code for waiting on the handle from ShellExecuteEx()

import win32com.shell.shell as shell
import win32event
#fMask = SEE_MASK_NOASYNC(0x00000100) = 256 + SEE_MASK_NOCLOSEPROCESS(0x00000040) = 64
dict = shell.ShellExecuteEx(fMask = 256 + 64, lpFile='Notepad.exe', lpParameters='Notes.txt')
hh = dict['hProcess']
print hh
ret = win32event.WaitForSingleObject(hh, -1)
print ret



回答2:


The return value of ShellExecute is what you need to test. You return that from print_file, but you then ignore it. You need to capture it and check that.

hinstance = print_file(i, printer_name)
if hinstance > 32:
    ....

However, having your print_file function leak implementation detail like an HINSTANCE seems bad. I think you would be better to check the return value of ShellExecute directly at the point of use. So try to move the > 32 check inside print_file.

Note that ShellExecute has very weak error reporting. If you want proper error reporting then you should use ShellExecuteEx instead.

Your delete/sleep loop is very brittle indeed. I'm not quite sure I can recommend anything better since I'm not sure what you are trying to achieve. However, expect to run into trouble with that part of your program.



来源:https://stackoverflow.com/questions/18025882/how-to-determine-if-win32api-shellexecute-was-successful-using-hinstance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!