5

元の問題に対する答えを探していました.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() コマンドに割り当てて、hinstance をキャプチャし、関数の最後に明示的に返すことに注意してください。これも機能しません。

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

2 に答える 2

6

ではShellExecute、印刷がいつ完了するかはわかりません。これは、ファイルのサイズと、プリンタ ドライバがコンテンツをバッファリングするかどうかによって異なります (たとえば、プリンタは、用紙トレイがいっぱいになるのを待っている可能性があります)。

この SO answerによると、コマンドが完了するのを待つため、より良い解決策のように見えsubprocess.call()ます。この場合のみ、ファイルに関連付けられたexeを取得するためにレジストリを読み取る必要があります。

ShellExecuteExpywin32から入手可能で、次のようなことができます:

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
于 2013-08-03T07:53:58.750 に答える
1

の戻り値はShellExecute、テストする必要があるものです。からそれを返しprint_fileますが、それを無視します。それをキャプチャして確認する必要があります。

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

ただし、print_file関数リークの実装の詳細をのようにするのHINSTANCEは悪いようです。ShellExecuteの戻り値は使用時に直接確認した方が良いと思います。> 32そのため、チェックを内側に移動してみてくださいprint_file

ShellExecuteエラー報告が非常に弱いことに注意してください。適切なエラー報告が必要な場合は、ShellExecuteEx代わりに使用する必要があります。

あなたの削除/スリープループは確かに非常に脆弱です。あなたが何を達成しようとしているのかわからないので、もっと良いものをお勧めできるかどうかはわかりません. ただし、プログラムのその部分で問題が発生することを想定してください。

于 2013-08-02T20:56:38.023 に答える