如何使用hinstance确定win32api.ShellExecute是否成功?

时间:2013-08-02 20:49:13

标签: python winapi python-2.7 pywin32 shellexecute

我一直在寻找原始问题的答案。我如何(以编程方式)确定我的win32api.ShellExecute语句成功执行,如果成功执行,则执行os.remove()语句。

研究我发现ShellExecute()调用返回HINSTANCE。进一步挖掘我发现ShellExecute()将返回一个HINSTANCE> 32如果成功的话。我的问题/问题是,如何使用它来控制程序的其余部分?我尝试使用if HINSTANCE> 32:语句来控制下一部分,但我收到了NameError: name 'hinstance' is not defined消息。通常这不会让我感到困惑,因为这意味着我需要在引用之前定义变量'hinstance';但是,因为我认为ShellExecute应该返回HINSTANCE,我认为它可以使用吗?

这是我的完整代码,我试图实现这一点。请注意,在我的print_file()中,我将hinstance分配给完整的win32api.ShellExecute()命令,以尝试捕获实例并在函数结束时显式返回它。这也不起作用。

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()

2 个答案:

答案 0 :(得分:5)

使用ShellExecute,您永远不会知道打印何时完成,这取决于文件的大小以及打印机驱动程序是否缓冲内容(打印机可能正在等待您填充纸盘,例如)。

根据this SO answer,看起来subprocess.call()是一个更好的解决方案,因为它等待命令完成,只有在这种情况下你才需要读取注册表来获取与之关联的exe文件。

ShellExecuteEx可从pywin32获得,您可以执行以下操作:

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)

编辑:从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

答案 1 :(得分:1)

ShellExecute的返回值是您需要测试的。你从print_file返回,但你忽略它。你需要抓住它并检查它。

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

但是,将print_file函数泄漏实现细节视为HINSTANCE似乎很糟糕。我认为你最好直接在使用点检查ShellExecute的返回值。因此,请尝试在> 32内移动print_file

请注意,ShellExecute的错误报告非常弱。如果您需要正确的错误报告,则应使用ShellExecuteEx代替。

你的删除/睡眠循环确实非常脆弱。我不太确定我能推荐什么更好,因为我不确定你想要达到的目的。但是,预计会遇到程序中的那部分问题。