WaitForSingleObject不起作用-无效的句柄

时间:2020-11-02 14:58:10

标签: python file winapi server

我目前正在为客户端提供代码,该代码可以从云中下载文件。客户端会临时下载文件,并在关闭(终止)文件后将其发送回云中。 这是完整的代码:

import socket
import os
from OpenFile import *
from Registry_Change import *
import win32con
import win32api
import win32event
from win32com.shell import shellcon
from win32com.shell.shell import ShellExecuteEx


class Application(object):
    def __init__(self):
        """
        :param request: the request of the file to receive from server
        """
        # initiates request (clicked file path)
        self.request = sys.argv[SECOND]

        reg = Read_Registry()
        ip, port = reg.get_ip_port()

        self.ip = ip
        self.port = port

        # initiates socket
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((self.ip, self.port))
            # sends the request to the server
            Application.send_request_to_server(self.sock, "DOWNLOAD_FILE " + self.request)
            format = Application.read_server_response(self.sock).decode()
            self.path_file = self.download(format)
            self.start_file_and_wait()
            self.sock.close()
        except Exception as msg:
            print(win32api.GetLastError())
            print("connection error:", msg)
@staticmethod
def valid_file(path):
    """
    checks if the path is a file that exists
    """
    if os.path.isfile(path):
        return True
    return False

@staticmethod
def delete_file(file_path):
    """
    deletes file
    """
    os.remove(file_path)

@staticmethod
def read_server_response(server_socket_choice):
    """
    reads the length and according to that, it reads the rest
    of the message
    """
    try:
        length_of_message = server_socket_choice.recv(BYTE).decode()
        if length_of_message.isdigit():
            return server_socket_choice.recv(int(length_of_message))
    except Exception as msg:
        print("at read_server_response:", msg)
        return SERVER_FELL

@staticmethod
def send_request_to_server(server_socket, request):
    """
    Send the request to the server.
    First the length of the request (2 digits), then the request itself
    Example: '04EXIT'
    Example: '12DIR c:\cyber'
    """
    server_socket. \
        send((str(len(request)).zfill(MSG_FILL) + request).encode())

def download(self, format):
    """
    saves the given chunks to a file in the client
    """
    try:
        file = Application.new_format_path(self.request, format)
        new_location = Application.make_new_file_path(TEMPORARY_FILES, file)
        # check if the file is valid
        check_len = self.sock.recv(BYTE).decode()
        check = self.sock.recv(int(check_len))
        if check != FILE_DOESNT_EXIST:
            client_file = open(new_location, 'wb')
            # write what we took out
            client_file.write(check)
            done = False
            while not done:
                byte_message_len = self.sock.recv(BYTE)
                length = byte_message_len.decode()
                if length.isdigit():
                    real_len = int(length)
                    data = self.sock.recv(real_len)
                if data == FILE_END:
                    done = True
                else:
                    client_file.write(data)
            client_file.close()
            return new_location
        else:
            return 'nothing'
    except Exception as msg:
        print("at download:", msg)

def upload(self, file_path):
    """
    Sends a file from the server to the client
    """
    if Application.valid_file(file_path):
        client_file = open(file_path, 'rb')
        content = client_file.read(BYTE_NUMBER)
        while content != b'':
            Application.send_binary_response_to_server(content, self.sock)
            content = client_file.read(BYTE_NUMBER)
        client_file.close()
        Application.send_binary_response_to_server(FILE_END, self.sock)
        Application.delete_file(file_path)
        Application.make_imaginary_file(file_path)
        return Application.read_server_response(self.my_socket)
    else:
        Application.send_response_to_server(FILE_DOESNT_EXIST, self.sock)
        return FILE_DOESNT_EXIST

@staticmethod
def make_new_file_path(new_path, folder):
    """
    :param new_path: new path of file to merge
    :return: the new path
    """
    comp = folder.split("\\")
    return new_path + "\\" + comp[END]

@staticmethod
def new_format_path(path, format):
    """
    :param format: the new format
    :return: the same path but with new format
    """
    path_format = path.split('.')
    path_format[SECOND] = format
    return ".".join(path_format)

def start_file_and_wait(self):
    """
    :param fname: the file path - temporary
    :return: opens and continues when closed
    """
    rc = ShellExecuteEx(
        fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
        nShow=win32con.SW_SHOW,
        lpFile=self.path_file)
    hproc = rc['hProcess']
    win32event.WaitForSingleObject(hproc, win32event.INFINITE)
    win32api.CloseHandle(hproc)


app = Application()

现在,win32event.WaitForSingleObject(hproc,win32event.INFINITE)命令不起作用,并返回错误:“(6,'WaitForSingleObject','句柄无效。')”。 当我尝试在单独的文件中使用start_file_and_wait(self)函数时,它起作用了:

def start_file_wait(fname):
import win32con
import win32api
import win32event
from win32com.shell import shellcon
from win32com.shell.shell import ShellExecuteEx
rc = ShellExecuteEx(
    fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
    nShow=win32con.SW_SHOW,
    lpFile=fname)
hproc = rc['hProcess']
win32event.WaitForSingleObject(hproc, win32event.INFINITE)
win32api.CloseHandle(hproc)


def main():
    start_file_wait("E:\\12\\alice-chapter-1.txt")
    print("hi")

if __name__ == '__main__':
    main()

我不知道如何解决它。有人能帮我吗? 谢谢!

1 个答案:

答案 0 :(得分:0)

它不适用于不是文本文件的文件

正如您所说,根据parameter,您没有为ShellExecuteEx指定合适的动词:

lpVerb:

...此参数可以为NULL,在这种情况下,默认动词为 如果可用,则使用。如果不是,则使用“ open”动词。如果两个动词都不是 如果可用,系统将使用注册表中列出的第一个动词。

如果找不到关联的应用程序来打开文件,它可能会失败并返回无效的hProcess句柄。您应该根据打开的文件指定一个有效的动词。或将与该文件相对应的应用程序的可执行文件指定为lpFile,并将文件指定为lpParameters

您可以参考以下文档: Launching Applications

相关问题