[RESOLVED] Display of a selection window during installation

Questions about WAPT Packaging / Requests and help regarding Wapt packages.
Forum Rules
Community Forum Rules
* English support on www.reddit.com/r/wapt
* French community support is available on this forum
* Please prefix the topic title with [RESOLVED] if it is resolved.
* Please do not edit a topic that is tagged [RESOLVED]. Open a new topic referencing the old one.
* Specify the installed WAPT version, full version, and build number (2.2.1.11957 / 2.2.2.12337 / etc.) as well as the Enterprise/Discovery edition.
* Versions 1.8.2 and earlier are no longer supported. The only questions accepted regarding version 1.8.2 are related to upgrading to a supported version (2.1, 2.2, etc.).
* Specify the server OS (Linux/Windows) and version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specify the OS of the administration/package creation machine and the machine with the problematic agent, if applicable (Windows 7/10/11/Debian 11/etc.).
* Avoid asking multiple questions when opening a topic, otherwise it may be ignored. If there are multiple topics, open separate topics, preferably one after the other and not all at the same time (i.e., do not spam the forum).
* Include code snippets, screenshots, and other images directly in the post. Links to Pastebin, Bitly, and other third-party sites will be systematically removed.
* As with any community forum, support is provided voluntarily by members. If you require commercial support, you can contact Tranquil IT's sales department at 02.40.97.57.55
Locked
Mikael S
Messages: 26
Registration: January 20, 2025 - 3:54 PM

January 20, 2025 - 4:08 PM

Hello,

For a very specific task, I need to display a dialog box to select an action to perform during package installation on the machine receiving the installation.

I've been using `waptguihelper.grid_dialog` so far. However, this works fine with PyScripter, but only because it's my session. Installing packages from the console doesn't work.

I know the trick for executables using `get_active_sessions` and then `start_interactive_process`. But `grid_dialog` doesn't have a session parameter.

Is there a way to generate this dialog box for the active session and retrieve the selected action?




Sincerely,
User avatar
sfonteneau
WAPT Expert
Messages: 2318
Registered: July 10, 2014 - 11:52 PM
Contact :

January 20, 2025 - 4:39 PM

Good morning

We can ask the session to execute:

Code: Select all

waptpython -c "import json;import waptguihelper;waptguihelper.grid_dialog('hello',json.dumps({'hello':'hello'}))"
The problem is, I don't think the current code can retrieve the output value. We'd need to look into this further; it would be an interesting option
Mikael S
Messages: 26
Registration: January 20, 2025 - 3:54 PM

January 24, 2025 - 1:10 PM

Indeed, there's no going back.

I tried using `print` to retrieve the output, but it doesn't seem as straightforward with the `win32process.CreateProcess` function at first glance.

I'll probably write it to a file and read it from the main program. For now, I don't see an easier way.
User avatar
sfonteneau
WAPT Expert
Messages: 2318
Registered: July 10, 2014 - 11:52 PM
Contact :

January 24, 2025 - 2:06 PM

I checked, I have something that works ;)

Code: Select all

# -*- 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)
However, it's up to you to manage the while loop to avoid an infinite wait
Mikael S
Messages: 26
Registration: January 20, 2025 - 3:54 PM

February 4, 2025 - 10:22

Okay, that works. It was a bit complex to pass all the arguments with quotes and retrieve the values, especially since it's a list of values ​​that I'm sending.

But for those who are interested, here's part of the code

Code: Select all

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))
However, the loop seems fine to me. I don't see in what scenario it could cause a problem.
User avatar
dcardon
WAPT Expert
Messages: 1929
Registration: June 18, 2014 - 09:58
Location: Saint Sébastien sur Loire
Contact :

February 4, 2025 - 11:59

Hi Mikaël,

thanks for the feedback :-), I'm marking the topic as RESOLVED.

Denis
Denis Cardon - Tranquil IT
Share your experiences on WAPT! Send us your blog and article URLs in the "Your Opinion of the forum, and we'll feature them on the WAPT
Locked