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

Domande sul packaging WAPT / Richieste e assistenza sui pacchetti Wapt.
Regole del forum
Regole del forum della community
* Supporto in inglese su www.reddit.com/r/wapt
* Supporto della community in francese disponibile su questo forum
* Si prega di anteporre [RISOLTO] al titolo dell'argomento se è stato risolto.
* Si prega di non modificare un argomento contrassegnato con [RISOLTO]. Aprire un nuovo argomento facendo riferimento a quello precedente.
* Specificare la versione di WAPT installata, la versione completa e il numero di build (2.2.1.11957 / 2.2.2.12337 / ecc.) nonché l'edizione Enterprise/Discovery.
* Le versioni 1.8.2 e precedenti non sono più supportate. Le uniche domande accettate relative alla versione 1.8.2 riguardano l'aggiornamento a una versione supportata (2.1, 2.2, ecc.).
* Specificare il sistema operativo del server (Linux/Windows) e la versione (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specificare il sistema operativo della macchina di amministrazione/creazione dei pacchetti e della macchina con l'agente problematico, se applicabile (Windows 7/10/11/Debian 11/ecc.).
* Evitare di porre più domande quando si apre una discussione, altrimenti potrebbe essere ignorata. Se ci sono più discussioni, aprirle separatamente, preferibilmente una dopo l'altra e non tutte contemporaneamente (ovvero, non intasare il forum).
* Includere frammenti di codice, screenshot e altre immagini direttamente nel post. I link a Pastebin, Bitly e altri siti di terze parti verranno sistematicamente rimossi.
* Come in qualsiasi forum della community, il supporto è fornito volontariamente dai membri. Se si necessita di supporto commerciale, è possibile contattare il reparto vendite di Tranquil IT al numero 02.40.97.57.55
Bloccato
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

20 gennaio 2025 - 16:08

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,
Avatar utente
sfontenau
Esperto WAPT
Messaggi: 2312
Registrato: 10 luglio 2014 - 23:52
Contatto:

20 gennaio 2025 - 16:39

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
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

24 gennaio 2025 - 13:10

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.
Avatar utente
sfontenau
Esperto WAPT
Messaggi: 2312
Registrato: 10 luglio 2014 - 23:52
Contatto:

24 gennaio 2025 - 14:06

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
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

4 febbraio 2025 - 10:22

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.
Avatar utente
dcardon
Esperto WAPT
Messaggi: 1908
Registrazione: 18 giugno 2014 - 09:58
Ubicazione: Saint Sébastien sur Loire
Contatto:

4 febbraio 2025 - 11:59

Ciao Mikaël,

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

Denis
Denis Cardon - Tranquil IT
Condividi le tue esperienze su WAPT! Inviaci gli URL dei tuoi blog e articoli nella "La tua opinione del forum e li pubblicheremo sul di WAPT
Bloccato