Pagina 1 di 1

[RISOLTO] Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 20 gennaio 2025 - 16:08
di Mikael S
Salve,

per un compito molto specifico, ho bisogno di visualizzare una finestra di dialogo per selezionare un'azione da eseguire durante l'installazione di un pacchetto sulla macchina che riceve l'installazione.

Finora ho usato `waptguihelper.grid_dialog`. Tuttavia, questo funziona correttamente con PyScripter, ma solo perché si tratta della mia sessione. L'installazione di pacchetti dalla console non funziona.

Conosco il trucco per gli eseguibili usando `get_active_sessions` e poi `start_interactive_process`. Ma `grid_dialog` non ha un parametro di sessione.

Esiste un modo per generare questa finestra di dialogo per la sessione attiva e recuperare l'azione selezionata?




Cordiali saluti,

Re: Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 20 gennaio 2025 - 16:39
di sfontenau
Buongiorno

Possiamo chiedere alla sessione di eseguire:

Codice: Seleziona tutto

waptpython -c "import json;import waptguihelper;waptguihelper.grid_dialog('hello',json.dumps({'hello':'hello'}))"
Il problema è che non credo che il codice attuale riesca a recuperare il valore di output. Dovremmo approfondire la questione; sarebbe un'opzione interessante

Re: Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 24 gennaio 2025 - 13:10
di Mikael S
In effetti, non si può tornare indietro.

Ho provato a usare `print` per recuperare l'output, ma a prima vista non sembra così semplice con la funzione `win32process.CreateProcess`.

Probabilmente lo scriverò su un file e lo leggerò dal programma principale. Per ora, non vedo un modo più semplice.

Re: Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 24 gennaio 2025 - 14:06
di sfontenau
Ho controllato, ho qualcosa che funziona ;)

Codice: Seleziona tutto

# -*- 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)
Tuttavia, spetta a te gestire il ciclo while per evitare un'attesa infinita

Re: Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 4 febbraio 2025 - 10:22
di Mikael S
Ok, funziona. È stato un po' complesso passare tutti gli argomenti tra virgolette e recuperare i valori, soprattutto perché sto inviando un elenco di valori.

Ma per chi fosse interessato, ecco una parte del codice

Codice: Seleziona tutto

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))
Tuttavia, il loop mi sembra corretto. Non vedo in quale scenario potrebbe causare problemi.

Re: Visualizzazione di una finestra di selezione durante l'installazione

Pubblicato: 4 febbraio 2025 - 11:59
di dcardon
Ciao Mikaël,

grazie per il feedback :-), contrassegno la discussione come RISOLTA.

Denis