WaitForSingleObject не работает — недопустимый дескриптор

#python #file #winapi #server

#python #файл #winapi #сервер

Вопрос:

В настоящее время я исправляю код для клиента, который может загружать файлы из облака. Клиент временно загружает файл, и когда файл закрывается (завершается), он отправляется обратно в облако. Вот полный код:

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

Теперь, событие win32.WaitForSingleObject(hproc, win32event.БЕСКОНЕЧНАЯ) команда не работает и возвращает ошибку: «(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. Он не работает с файлами, которые не являются текстовыми файлами!!!

2. Я не программирую на Python, но я собираюсь предположить, что вы создаете поток / процесс, а затем ожидаете, что этот поток / процесс вернется с WaitForSingleObject?

Ответ №1:

Он не работает с файлами, которые не являются текстовыми файлами

Как вы сказали, вы не указали подходящий глагол для ShellExecuteEx , в соответствии с параметром:

lpVerb :

… Этот параметр может быть нулевым, и в этом случае используется глагол по умолчанию, если он доступен. Если нет, используется глагол «открыть». Если ни один из глаголов недоступен, система использует первый глагол, указанный в реестре.

Может произойти сбой и вернуть недопустимый hProcess дескриптор, если он не может найти соответствующее приложение для открытия файла. Вы должны указать допустимый глагол в соответствии с файлом, который вы открываете. Или укажите исполняемый файл приложения, соответствующий файлу как lpFile , и укажите файл как lpParameters .

Вы можете обратиться к следующему документу: Запуск приложений