Página 1 de 1

[RESUELTO] Visualización de una ventana de selección durante la instalación

Publicado: 20 de enero de 2025 - 16:08
por Mikael S
Hola,

para una tarea muy específica, necesito mostrar un cuadro de diálogo para seleccionar una acción a realizar durante la instalación de un paquete en la máquina receptora.

Hasta ahora he estado usando `waptguihelper.grid_dialog`. Sin embargo, esto funciona bien con PyScripter, pero solo porque es mi sesión. Instalar paquetes desde la consola no funciona.

Conozco el truco para ejecutables usando `get_active_sessions` y luego `start_interactive_process`. Pero `grid_dialog` no tiene un parámetro de sesión.

¿Hay alguna manera de generar este cuadro de diálogo para la sesión activa y recuperar la acción seleccionada?




Atentamente,

Re: Visualización de una ventana de selección durante la instalación

Publicado: 20 de enero de 2025 - 16:39
por sfonteneau
Buen día

Podemos pedirle a la sesión que ejecute:

Código: Seleccionar todo

waptpython -c "import json;import waptguihelper;waptguihelper.grid_dialog('hello',json.dumps({'hello':'hello'}))"
El problema es que no creo que el código actual pueda recuperar el valor de salida. Deberíamos analizarlo más a fondo; sería una opción interesante

Re: Visualización de una ventana de selección durante la instalación

Publicado: 24 de enero de 2025 - 13:10
por Mikael S
De hecho, no hay vuelta atrás.

Intenté usar `print` para obtener la salida, pero a primera vista no parece tan sencillo con la función `win32process.CreateProcess`.

Probablemente la escribiré en un archivo y la leeré desde el programa principal. Por ahora, no veo una forma más fácil.

Re: Visualización de una ventana de selección durante la instalación

Publicado: 24 de enero de 2025 - 14:06
por sfonteneau
Lo revisé, tengo algo que funciona ;)

Código: Seleccionar todo

# -*- coding: utf-8 -*-
from setuphelpers import *

import os
import win32api
import win32con
import win32process
import win32security
import win32ts
import win32profile
import win32pipe
import win32file

try:
    from waptenterprise.waptservice.enterprise import get_active_sessions
except:
    from waptservice.enterprise import get_active_sessions


def start_interactive_process2(app_filename, cmdline=None, session_id=None, hide=True, minimize=False):

    if session_id is None:
        session_id = win32ts.WTSGetActiveConsoleSessionId()
    if session_id == 0xffffffff:
        return None

    CREATE_BREAKAWAY_FROM_JOB = 0x1000000
    priority = win32con.NORMAL_PRIORITY_CLASS | win32con.CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB
    startup = win32process.STARTUPINFO()
    startup.lpDesktop = None
    startup.dwFlags = win32con.STARTF_USESTDHANDLES | win32con.STARTF_USESHOWWINDOW
    startup.wShowWindow = win32con.SW_HIDE

    token = win32ts.WTSQueryUserToken(session_id)


    saAttr = win32security.SECURITY_ATTRIBUTES()
    saAttr.bInheritHandle = True

    read_pipe, write_pipe = win32pipe.CreatePipe(saAttr, 0)
    win32api.SetHandleInformation(read_pipe, win32con.HANDLE_FLAG_INHERIT, 0)


    startup.hStdOutput = write_pipe
    startup.hStdError = write_pipe
    startup.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)

    if cmdline is None:
        cmd = f'"{app_filename}"'
    else:
        cmd = f'"{app_filename}" {cmdline}'

    working_directory = "C:\\Windows\\System32"

    environment = win32profile.CreateEnvironmentBlock(token, False)
    new_token = win32security.DuplicateTokenEx(token, win32security.SecurityDelegation, win32security.TOKEN_ALL_ACCESS, win32security.TokenPrimary)

    process_info = win32process.CreateProcessAsUser(
        new_token,
        None,
        f'cmd.exe /c {cmd}',
        None, None,
        True,
        priority,
        environment,
        working_directory,
        startup
    )

    win32api.CloseHandle(token)
    win32api.CloseHandle(new_token)

    win32file.CloseHandle(write_pipe)

    output = b""
    while True:
        try:
            chunk = win32file.ReadFile(read_pipe, 4096)[1]
            if not chunk:
                break
            output += chunk
        except Exception:
            break

    win32file.CloseHandle(read_pipe)

    return output.decode("utf-8", errors="ignore")




def install():
    list_session = get_active_sessions()
    for s in list_session:
        output = start_interactive_process2('''waptpythonw -c "import json;import waptguihelper;print(waptguihelper.grid_dialog('hello',json.dumps({'hello':'hello'})))"''',session_id=s)
        print(output)
Sin embargo, depende de usted administrar el bucle while para evitar una espera infinita

Re: Visualización de una ventana de selección durante la instalación

Publicado: 4 de febrero de 2025 - 10:22 a. m.
por Mikael S
Bien, funciona. Fue un poco complejo pasar todos los argumentos entre comillas y recuperar los valores, sobre todo porque estoy enviando una lista de valores.

Pero para aquellos que estén interesados, aquí está parte del código

Código: Seleccionar todo

titre = "'Choix'"
json_list_backup = json.dumps(list_choix).replace('"', "'")

command_line = f'import json;import waptguihelper;print(waptguihelper.grid_dialog({titre},{json_list}, waptguihelper.GRT_SELECTED))'
list_session = get_active_sessions()
for s in list_session:
    selected_backup = ast.literal_eval(start_interactive_process2(f'waptpythonw -c "{command_line}"', session_id=s))
Sin embargo, el bucle me parece correcto. No veo en qué situación podría causar un problema.

Re: Visualización de una ventana de selección durante la instalación

Publicado: 4 de febrero de 2025 - 11:59 a. m.
por dcardon
Hola Mikaël,

gracias por tus comentarios :-), marco el tema como RESUELTO.

Denis