Программа не работает после создания exe файла через Pyinstaller(Failed to execute script)

Я написал программу на Python 3.9 используя библиотеки Numpy, Sympy, sys, которая замечательно работает в PyCharm. Вот ее код

import numpy as np
from sympy import *
import sys

f = open("result.txt", 'w+')
for line in sys.stdin:
    f.write(line)
f.close()
f = open("result.txt", 'r')
data = f.read().split("\n")
i = 0
while i < len(data):
    data[i] = data[i].split(' ')
    i += 1
amount = int(data[0][0])
matrix = np.zeros((amount, amount))
i = 0
j = 0

while i < amount:
    while j < amount:
        matrix[i, j] = int(data[i + 1][j])
        j += 1
    j = 0
    i += 1
i = 0
j = 0
counter = 0
formula = 1
while i < amount:
    while j < amount:
        if matrix[i, j] == 1:
            x = symbols(str(i + 1))
            y = symbols(str(j + 1))
            if counter == 0:
                formula = (~x | ~y)
                counter += 1
            else:
                formula = formula & (~x | ~y)
        j += 1
    j = 0
    i += 1
formula_to_string = pycode(simplify_logic(formula, form='dnf', force=True))
massive_to_parse = formula_to_string.split("or")
k = 1
i = 0
while i < len(massive_to_parse):
    print("{", end='')
    while k < amount + 1:
        try:
            massive_to_parse[i].index(str(k))
        except ValueError:
            print("V",k, sep='', end='')
        finally:
            k += 1
    print("}-максимальное внутренне устойчивое множество")
    k = 1
    i += 1

Затем я создаю exe файл через команду(pyinstaller 4.3)

pyinstaller main.py

Во время создания exe он выдает такие WARNING:

WARNING: Several hooks defined for module 'win32ctypes.core'. Please take care they do not conflict.
WARNING: Hidden import "pkg_resources.py2_warn" not found!
WARNING: Hidden import "pkg_resources.markers" not found!
WARNING: lib not found: api-ms-win-core-path-l1-1-0.dll dependency of C:\Users\boris\AppData\Local\Programs\Python\Python39\python39.dll

Ну и после создания exe, когда я запускаю его выдает уже вот такую ошибку Ошибка

Итак, может ли это быть из за версии 3.9 Python? Следует ли попробовать на 3.8 например? Или может проблема в версии pyinstaller? Или мне надо установить какие-то дополнительные пакеты?


Ответы (1 шт):

Автор решения: Kers

Пример кода в продолжении комментариев о использовании встраиваемого python.

Если вы используете embedded python для примера положим его в папку venv рядом с нашим скриптом main.py. Устанавливаете в него все необходимые зависимости. Проверяем работы через консоль, из директории со скриптом набираем:

venv\python.exe main.py

Все должно работать.

Теперь создаем запускающий exe на любом компилируемом языке. Приведу базовые примеры для Golang и C#.

Go:

package main

import "github.com/gonutz/ide/w32"
import (
    "os"
    "os/exec"
)


func main() {
    // hideConsole()
    console(".\\venv\\python.exe main.py")

}

func console(x string) {
    cmd := exec.Command("cmd", "/C", x)
    cmd.Stdout = os.Stdout
    cmd.Stdin = os.Stdin
    cmd.Stderr = os.Stderr
    cmd.Run()

}

func hideConsole() {
    console := w32.GetConsoleWindow()
    if console == 0 {
        return // no console attached
    }
    _, consoleProcID := w32.GetWindowThreadProcessId(console)
    if w32.GetCurrentProcessId() == consoleProcID {
        w32.ShowWindowAsync(console, w32.SW_HIDE)
    }
}

hideConsole() можно раскомментировать если нужно скрывать консоль.

Аналогичный вариант на C#

using System;
using System.Diagnostics;
using System.Reflection;

namespace PyRunner.Net
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            Console.WriteLine(path);

            string cmd = "main.py";

            var proc = new ProcessStartInfo()
            {
                UseShellExecute = false,
                WorkingDirectory = path,
                FileName = path + @"\venv\python.exe",
                Arguments = cmd,
                WindowStyle = ProcessWindowStyle.Hidden
            };

            Process.Start(proc);
        }
    }
}

Как упоминалось выше издержкой данного решения является несколько раздутый объём программы.

По коду... for line in sys.stdin получается вешает программу. Минимально воспроизводимый пример прилагается.

import sys
for line in sys.stdin:
    pass

Попробуйте заменить на:

with open("result.txt", 'w+') as f:
    for line in sys.stdin:
        if 'exit' == line.strip():
            break
        f.write(line)

Так у Вас будет возможность продолжить программу после ввода 'exit'

→ Ссылка