When I compile my code into an exe it gives me these errors.I need to fix this so that my exe works. As I understand it is from the Patool library but I can't get anything to solve it. My code works fine when I run it in visual studio code.
Traceback (most recent call last): File "CraftersCR.py", line 7, in <module> import patoolib File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 935, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 419, in exec_module File "patoolib\__init__.py", line 26, in <module> File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 935, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 419, in exec_module File "patoolib\fileutil.py", line 21, in <module> File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 935, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 419, in exec_module File "patoolib\log.py", line 40, in <module>AttributeError: 'NoneType' object has no attribute 'encoding'
import subprocessimport minecraft_launcher_libimport webbrowserimport shutilimport jsonimport tkinterimport patoolibimport os, sysfrom os import pathfrom tkinter import *from PIL import ImageTk, Imagefrom pydrive2.auth import GoogleAuthfrom pydrive2.drive import GoogleDrivefrom pathlib import Pathdirectorio_credenciales = 'credentials_module.json'config_file = 'config.json' #archivo de configuraciondef resourse_path(relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) ventana = tkinter.Tk()ventana.geometry('1200x800') #tamaño de la ventana en Pxventana.title('Crafters CR')ventana.resizable(False,False) #para que no se pueda cambiar de tamaño.imagenL = ImageTk.PhotoImage(Image.open('C:/Users/braya/Desktop/CraftersCR-env/asgaroth.jpg').resize((1200, 800)))lblImagen = Label(ventana, image=imagenL)lblImagen.place(x=0, y=0, relwidth=1, relheight=1)user_window = os.environ["USERNAME"]minecraft_directory = f"C:\\Users\\{user_window}\\AppData\\Roaming\\.asgaroth"bt_ejecutar_minecraft = tkinter.Button()bt_instalar_versiones = tkinter.Button()bt_instalar_forge = tkinter.Button()bt_instalar_fabric = tkinter.Button()label_nombre = tkinter.Label(text='Usuario')label_ram = tkinter.Label(text='Ram')entry_versiones = tkinter.Entry()entry_nombre = tkinter.Entry()entry_ram = tkinter.Entry()versiones_forge = [0]versiones_fabric = [0]# Muestra las versiones en un desplegableversiones_instaladas = minecraft_launcher_lib.utils.get_installed_versions(minecraft_directory)versiones_instaladas_lista = []for versiones_instaladas in versiones_instaladas: versiones_instaladas_lista.append(versiones_instaladas['id'])if len(versiones_instaladas_lista) != 0: vers = tkinter.StringVar(ventana) vers.set(versiones_instaladas_lista[0])elif len(versiones_instaladas_lista) == 0: vers = tkinter.StringVar(ventana) vers.set('sin versiones instaladas') versiones_instaladas_lista.append('sin versiones instaladas')versiones_menu_desplegable = tkinter.OptionMenu(ventana, vers, *versiones_instaladas_lista) #para crear el desplegableversiones_menu_desplegable.config()def center_window(window, width, height): screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() x_coordinate = (screen_width - width) // 2 y_coordinate = (screen_height - height) // 2 window.geometry(f"{width}x{height}+{x_coordinate}+{y_coordinate}")ancho_ventana = 1200alto_ventana = 800center_window(ventana, ancho_ventana, alto_ventana)def load_config(): # Obtiene la ruta del directorio de inicio del usuario actual home_dir = Path.home() # Construye la ruta completa al archivo de configuración dentro del directorio del usuario config_file_path = home_dir / 'Desktop' / 'CraftersCR-env' / 'config.json' try: with open(config_file_path, 'r') as f: return json.load(f) except json.decoder.JSONDecodeError as e: print("Error al decodificar JSON:", e) # Manejar el error de manera elegante, como proporcionar una configuración predeterminada return {}# Cargar la configuración al inicio del programaconfig = load_config()# Función para guardar la configuración en el archivodef save_config(config): with open(config_file, 'w') as f: json.dump(config, f)# Actualizar UI con valores de configuraciónentry_nombre.insert(0, config.get('name', ''))entry_ram.insert(0, config.get('ram', '8')) # '2' es un valor predeterminado ejemplovers.set(config.get('version', versiones_instaladas_lista[0])) # Asegúrate de que este valor predeterminado es válido#funcion para iniciar minecraftdef instalar_minecraft(): version = entry_versiones.get() if version: minecraft_launcher_lib.install.install_minecraft_version(version, minecraft_directory) print(f'Se ha instalado la versión {version}') else: print('No se ingresó ninguna versión')def ejecutar_minecraft(): mine_user = entry_nombre.get() version = vers.get() ram = f"-Xmx{entry_ram.get()}G" # Guardar la configuración actualizada config['name'] = mine_user config['ram'] = entry_ram.get() config['version'] = version save_config(config) options = {'username': mine_user,'uuid': '','token': '','jvArguments': [ram,ram], # 4G son las gigas de ram a usar'launcherVersion': "0.0.1" } ventana.destroy() minecraft_command = minecraft_launcher_lib.command.get_minecraft_command(version, minecraft_directory, options) subprocess.run(minecraft_command)def instalar_versiones_normales(): global entry_versiones ventana_versiones = tkinter.Toplevel(ventana) ventana_versiones.title('Versiones') ventana_versiones.geometry('350x200') ventana_versiones.resizable(False,False) entry_versiones = tkinter.Entry(ventana_versiones) entry_versiones.place(x=0, y=0) #ajusta posicion a gusto bt_instalar_vers = tkinter.Button(ventana_versiones,command=instalar_minecraft,text='Instalar version') bt_instalar_vers.place(x=0, y=50) #ajusta posicion a gustodef ver_versiones_forge(): global vers_forge, versiones_forge, versiones_forge_menu_desplegable #obtener las nuevas opciones (pueden ser cualquier origen) nuevas_opciones = versiones_instaladas_Forge(entry_versiones.get()) #Actualizar el conjunto de opciones del OptionMenu versiones_forge_menu_desplegable['menu'].delete(0, 'end') for opcion in nuevas_opciones: versiones_forge_menu_desplegable['menu'].add_command(label=opcion, command=tkinter._setit(vers_forge, opcion)) vers_forge.set(nuevas_opciones[0] if nuevas_opciones else "") #establecer la primera opcion como la seleccionada def ver_versiones_fabric(): global vers_fabric, versiones_fabric, versiones_fabric_menu_desplegable #obtener las nuevas opciones nuevas_opciones = versiones_instaladas_fabric(entry_versiones.get()) #Actualizar el conjunto de opciones del OptionMenu versiones_fabric_menu_desplegable['menu'].delete(0, 'end') for opcion in nuevas_opciones: versiones_fabric_menu_desplegable['menu'].add_command(label=opcion, command=tkinter._setit(vers_fabric, opcion)) vers_fabric.set(nuevas_opciones[0] if nuevas_opciones else "") #establece la primera opcion como seleccionada def versiones_instaladas_Forge(version): numero = str(version)[2:] ultima_terminancion = None ultima_version = None versiones_forge_instaladas = [] for version_de_minecraft in minecraft_launcher_lib.forge.list_forge_versions(): if int(numero) >= 10: if ultima_version != version_de_minecraft[0:6]: if version_de_minecraft[2] == str(numero)[0] and ultima_terminancion != version_de_minecraft[5]: if version_de_minecraft[3] == str(numero)[1]: versiones_forge_instaladas.append(version_de_minecraft) ultima_terminancion = version_de_minecraft[5] ultima_version = version_de_minecraft[0:6] elif int(numero) >= 1 and version_de_minecraft[3] == '.': if ultima_version != version_de_minecraft[0:5]: if version_de_minecraft[2] == str(numero): versiones_forge_instaladas.append(version_de_minecraft) ultima_terminancion = version_de_minecraft[4] ultima_version = version_de_minecraft[0:5] return versiones_forge_instaladas def versiones_instaladas_fabric(version): numero = str(version)[2:] ultima_terminacion = None ultima_version = None versiones_fabric_instaladas = [] for version_de_minecraft in minecraft_launcher_lib.fabric.get_all_minecraft_versions(): if int(numero) >= 10: if ultima_version != version_de_minecraft['version'][0:6]: if len(version_de_minecraft['version']) >= 6: if version_de_minecraft['version'][2] == str(numero)[0] and ultima_terminacion != version_de_minecraft['version'][5]: if version_de_minecraft['version'][3] == str(numero)[1]: versiones_fabric_instaladas.append(version_de_minecraft['version']) print(version_de_minecraft['version']) ultima_version = version_de_minecraft['version'][0:6] elif int(numero) >= 1 and version_de_minecraft['version'][3] == '.': if ultima_version != version_de_minecraft['version'][0:5]: if version_de_minecraft['version'][2] == str(numero): versiones_fabric_instaladas.append(version_de_minecraft['version']) ultima_terminacion = version_de_minecraft['version'][4] ultima_version = version_de_minecraft['version'][0:5] return versiones_fabric_instaladasdef instalar_forge(): version = vers_forge.get() forge = minecraft_launcher_lib.forge.find_forge_version(version) minecraft_launcher_lib.forge.install_forge_version(version, minecraft_directory) print(f'Forge Instalado {forge}')def instalar_fabric(): version = vers_fabric.get() fabric = minecraft_launcher_lib.fabric.find_fabric_version(version) minecraft_launcher_lib.fabric.install_fabric(version, minecraft_directory) print(f'Fabric Instalado {fabric}')def instalar_versiones_forge(): global entry_versiones, vers_forge, versiones_forge, versiones_forge_menu_desplegable ventana_versiones = tkinter.Toplevel(ventana) ventana_versiones.title('Forge') ventana_versiones.geometry('350x200') ventana_versiones.resizable(False,False) entry_versiones = tkinter.Entry(ventana_versiones) entry_versiones.place(x=0, y=0) # Ajusta la posición según sea necesario bt_instalar_vers = tkinter.Button(ventana_versiones, command=instalar_forge, text='Instalar Forge') bt_instalar_vers.place(x=0, y=150) # Ajusta la posición según sea necesario bt_instalar_ver_vers = tkinter.Button(ventana_versiones, command=ver_versiones_forge, text='Versiones Forge') bt_instalar_ver_vers.place(x=0, y=50) # Ajusta la posición según sea necesario vers_forge = tkinter.StringVar(ventana_versiones) versiones_forge_menu_desplegable = tkinter.OptionMenu(ventana_versiones, vers_forge, *versiones_forge) versiones_forge_menu_desplegable.config() versiones_forge_menu_desplegable.place(x=0, y=100) def instalar_versiones_fabric(): global entry_versiones, vers_fabric, versiones_fabric, versiones_fabric_menu_desplegable ventana_versiones = tkinter.Toplevel(ventana) ventana_versiones.title('Fabric') ventana_versiones.geometry('350x200') ventana_versiones.resizable(False,False) entry_versiones = tkinter.Entry(ventana_versiones) entry_versiones.place(x=0, y=0) # Ajusta la posición según sea necesario bt_instalar_vers = tkinter.Button(ventana_versiones, command=instalar_fabric, text='Instalar Fabric') bt_instalar_vers.place(x=0, y=150) # Ajusta la posición según sea necesario bt_instalar_ver_vers = tkinter.Button(ventana_versiones, command=ver_versiones_fabric, text='Versiones Fabric') bt_instalar_ver_vers.place(x=0, y=50) # Ajusta la posición según sea necesario vers_fabric = tkinter.StringVar(ventana_versiones) versiones_fabric_menu_desplegable = tkinter.OptionMenu(ventana_versiones, vers_fabric, *versiones_fabric) versiones_fabric_menu_desplegable.config() versiones_fabric_menu_desplegable.place(x=0, y=100)def abrir_carpeta_mods(minecraft_directory): mods_path = os.path.join(minecraft_directory, "mods") os.makedirs(mods_path, exist_ok=True) # Crea la carpeta si no existe webbrowser.open(mods_path) # Abre la carpeta en el explorador de archivos# Función para iniciar sesión en Google Drive# Función para iniciar sesión en Google Drivedef login(): directorio_credenciales = 'credentials_module.json' # Asegúrate de tener tu archivo de credenciales correcto aquí gauth = GoogleAuth() gauth.LoadCredentialsFile(directorio_credenciales) if gauth.credentials is None or gauth.access_token_expired: gauth.LocalWebserverAuth() else: gauth.Authorize() gauth.SaveCredentialsFile(directorio_credenciales) return GoogleDrive(gauth)def descargar_archivo(file_id, ruta_descarga): # Función para descargar archivo desde Google Drive drive = login() archivo = drive.CreateFile({'id': file_id}) archivo.GetContentFile(ruta_descarga)def actualizar_mods(minecraft_directory): mods_path = os.path.join(minecraft_directory, "mods") # Ruta de la carpeta mods if os.path.exists(mods_path): for filename in os.listdir(mods_path): file_path = os.path.join(mods_path, filename) try: if os.path.isfile(file_path) or os.path.islink(file_path): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) except Exception as e: print(f'Error al eliminar {file_path}. Razón: {e}') else: os.makedirs(mods_path) archivo_mods_path = os.path.join(mods_path, "mods.rar") file_id = '1I2F-EZWycc1Qifa40wicNrGFmkDwBngC' descargar_archivo(file_id, archivo_mods_path) patoolib.extract_archive(archivo_mods_path, outdir=mods_path) os.remove(archivo_mods_path)def menu(): bt_instalar_versiones.config(command=instalar_versiones_normales,text='Versiones') bt_instalar_versiones.place(x=860, y=750) #ajusta posicion a gusto bt_instalar_forge.config(command=instalar_versiones_forge,text='Forge', bg= 'RED') bt_instalar_forge.place(x=930, y=750) #ajusta posicion a gusto bt_instalar_fabric.config(command=instalar_versiones_fabric,text='Fabric', bg= 'ORANGE') bt_instalar_fabric.place(x=980, y=750) label_nombre.place(x=100, y=680) #ajusta posicion a gusto label_ram.place(x=240, y=680) #ajusta posicion a gusto entry_nombre.place(x=100, y=705) #ajusta posicion a gusto entry_ram.place(x=240, y=705) #ajusta posicion a gusto bt_ejecutar_minecraft.config(command=ejecutar_minecraft,text='Iniciar',bg= 'GREEN') bt_ejecutar_minecraft.place(x=880, y=710) versiones_menu_desplegable.place(x=100, y=750) bt_mods = tkinter.Button(ventana, text="Mods", command=lambda: abrir_carpeta_mods(minecraft_directory),bg= 'lightblue') bt_mods.place(x=930, y=710) # Ajusta la posición según necesites # Crear el botón de actualizar en la interfaz gráfica y asociar la función actualizar_mods a su evento de clic bt_actualizar = tkinter.Button(ventana, text="Actualizar", command=lambda: actualizar_mods(minecraft_directory), bg='Yellow') bt_actualizar.place(x=980, y=710) # Ajustar la posición según sea necesario ventana.mainloop()menu()