Start MsgBox in User Session
Hallo,
Ich habe eine BAT Datei die mit Hilfe von VBS eine MsgBox aufruft.
Die BAT wird in Session 0 ausgeführt, somit sieht der User die MsgBox nicht.
Kann mir jemand helfen die Msf für den User sichtbar zu machen?
Ich habe eine BAT Datei die mit Hilfe von VBS eine MsgBox aufruft.
Die BAT wird in Session 0 ausgeführt, somit sieht der User die MsgBox nicht.
Kann mir jemand helfen die Msf für den User sichtbar zu machen?
@echo off
call :MsgBox "KAV Installieren?" "VBYesNo+VBQuestion" "KAV"
if errorlevel 7 (
echo NO
) else if errorlevel 6 (
echo YES
start "" "Setup.exe"
)
exit /b
:MsgBox prompt type title
setlocal enableextensions
set "tempFile=%temp%\%~nx0.%random%%random%%random%vbs.tmp"
>"%tempFile%" echo(WScript.Quit msgBox("%~1",%~2,"%~3") & cscript //nologo //e:vbscript "%tempFile%"
set "exitCode=%errorlevel%" & del "%tempFile%" >nul 2>nul
endlocal & exit /b %exitCode%
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 252834
Url: https://administrator.de/contentid/252834
Ausgedruckt am: 26.11.2024 um 10:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo Uragus,
seit Windows Vista können Prozesse, die in Session 0 laufen, nicht mehr über die MessageBox-API mit der User-Session komunizieren. Es gibt dafür jedoch den speziellen Win32-API-Aufruf
Ein MSDN-Artikel, der sich mit der Problematik beschäftigt, findet sich hier.
Evtl. findet sich ja auch per Google ein fertiges Tool, was genau das benötigte macht. Das Problem hatten bestimmt schon andere vor Dir.
Gruß
Friemler
[EDIT]
Aha, DerWoWusste macht seinem Namen wieder mal alle Ehre.
[/EDIT]
seit Windows Vista können Prozesse, die in Session 0 laufen, nicht mehr über die MessageBox-API mit der User-Session komunizieren. Es gibt dafür jedoch den speziellen Win32-API-Aufruf
WTSSendMessage
, den Du allerdings aus einem VBScript heraus nicht ansprechen kannst. Einzige Möglichkeit wäre demnach, ein kleines Programm (z.B. in C oder C++) zu schreiben, das WTSSendMessage
benutzt, um die per Parameter übergebene Message anzuzeigen. Dieses Programm kannst Du aus Deinem Batchscript heraus starten.Ein MSDN-Artikel, der sich mit der Problematik beschäftigt, findet sich hier.
Evtl. findet sich ja auch per Google ein fertiges Tool, was genau das benötigte macht. Das Problem hatten bestimmt schon andere vor Dir.
Gruß
Friemler
[EDIT]
Aha, DerWoWusste macht seinem Namen wieder mal alle Ehre.
[/EDIT]
Ich habe dann doch noch das Hilfsprogramm zum Anzeigen von Messageboxen aus Session 0 heraus geschrieben. Ich habe es mit der Open Source IDE CodeBlocks in C für MinGW entwickelt.
Fertig compilierte Binaries von MinGW findet man hier.
User @rubberman hat außerdem hier eine sehr schöne Anleitung veröffentlicht, um die CodeBlocks IDE incl. MinGW mit Hilfe eines von ihm entwickelten VBScripts als portable Version zu betreiben.
Für den folgenden Code eine Datei namens
Im gleichen Verzeichnis dann eine Batchdatei namens
In Zeile 7 muss man den Pfad zu dem Verzeichnis eintragen, in dem die
Gruß
Friemler
[EDIT]
Der Quellcode und das Build-Script erzeugen jetzt ein Unicode-fähiges Programm.
[/EDIT]
Fertig compilierte Binaries von MinGW findet man hier.
User @rubberman hat außerdem hier eine sehr schöne Anleitung veröffentlicht, um die CodeBlocks IDE incl. MinGW mit Hilfe eines von ihm entwickelten VBScripts als portable Version zu betreiben.
Für den folgenden Code eine Datei namens
main.c
anlegen und ihn dort hinein kopieren. Aber ACHTUNG!! Die Datei bitte in der Codierung UTF-8 mit BOM (Byte Order Mark) abspeichern!#define _WIN32_WINNT 0x0600 {{comment_single_line_double_slash:0}}
#include <sdkddkver.h> {{comment_single_line_double_slash:1}}
#define WIN32_LEAN_AND_MEAN {{comment_single_line_double_slash:2}}
#define STRICT 1 {{comment_single_line_double_slash:3}}
#define UNICODE {{comment_single_line_double_slash:4}}
#define _UNICODE {{comment_single_line_double_slash:5}}
#include <wchar.h> {{comment_single_line_double_slash:6}}
#include <stddef.h> {{comment_single_line_double_slash:7}}
#include <stdlib.h>
#include <windows.h> {{comment_single_line_double_slash:8}}
#include <wtsapi32.h>
/* ******************* */
/* Function prototypes */
/* ******************* */
INT wmain(INT argc, WCHAR *argv);
BOOL parseCmdLine(INT argc, WCHAR *argv, LPWSTR *message, LPWSTR *title, DWORD *buttons, WINBOOL *waitForClick, DWORD *timeout);
/* ************ */
/* Main program */
/* ************ */
INT wmain(INT argc, WCHAR *argv)
{
WCHAR exeName[_MAX_FNAME+1] = L"";
LPWSTR title = L"";
LPWSTR message = NULL;
DWORD buttons = MB_ICONINFORMATION | MB_OK;
DWORD titleLength = 0;
DWORD messageLength = 0;
DWORD timeout = 0;
WINBOOL waitForClick = FALSE;
DWORD response = -1;
DWORD physConSession = WTSGetActiveConsoleSessionId();
if (physConSession != 0xFFFFFFFF)
{
if (parseCmdLine(argc, argv, &message, &title, &buttons, &waitForClick, &timeout))
{
// Die Stringlängen müssen auch bei Unicode-Strings
// in Bytes angegeben werden!
messageLength = wcslen(message) * sizeof(*message);
titleLength = wcslen(title) * sizeof(*title);
WTSSendMessage(WTS_CURRENT_SERVER_HANDLE,
physConSession,
title, titleLength,
message, messageLength,
buttons,
timeout,
&response,
waitForClick);
}
else
{
_wsplitpath(argv, NULL, NULL, exeName, NULL);
_cwprintf(L"%ls \"Nachricht\" [-h:\"Titel\"] [-b:Buttons] [t:Wartezeit] [/w:true]\n" \
L"\n" \
L"Nachricht Text der anzuzeigenden Nachricht.\n" \
L"Titel Text, der in der Titelzeile der Message Box angezeigt wird.\n" \
L"Buttons Eine Zahl, in der der Typ des anzuzeigenden Icons, die darzustellen-\n" \
L" den Buttons und die Nummer des Default-Buttons codiert wird. Die\n" \
L" möglichen Werte finden sich in der Dokumentation der MessageBox-\n" \
L" Funktion auf MSDN.\n" \
L"Wartezeit Wartezeit in Sekunden, nach der sich die Message Box von selbst\n" \
L" schliesst. Ein Wert von 0 führt dazu, dass der Benutzer zuerst auf\n" \
L" einen der Buttons klicken muss, bis die Box geschlossen wird.\n" \
L"/w:true Wird dieser Parameter angegeben, wird erst nachdem die Message Box\n" \
L" geschlossen wurde, die Kontrolle an den Aufrufer zurück gegeben.\n" \
L"\n" \
L"Das Programm setzt den ERRORLEVEL entsprechend dem Rückgabewert der Message\n" \
L"Box. Die möglichen Werte und ihre Bedeutung findet man ebenfalls in der\n" \
L"Dokumentation der MessageBox-Funktion auf MSDN."\
L"\n",
exeName);
}
}
return response;
}
BOOL parseCmdLine(INT argc, WCHAR *argv, LPWSTR *message, LPWSTR *title, DWORD *buttons, WINBOOL *waitForClick, DWORD *timeout)
{
INT cnt;
WCHAR paramName[4];
for (cnt = 1; cnt < argc; cnt++)
{
wcsncpy(paramName, argv[cnt], 3);
paramName[3] = 0;
if (wcsnicmp(paramName, L"/h:", 3) == 0)
*title = &argv[cnt][3];
else if (wcsnicmp(paramName, L"/w:", 3) == 0)
*waitForClick = wcsnicmp(&argv[cnt][3], L"true", 4) == 0 ? TRUE : FALSE;
else if (wcsnicmp(paramName, L"/t:", 3) == 0)
*timeout = wcstoul(&argv[cnt][3], NULL, wcsnicmp(&argv[cnt][3], L"0x", 2) == 0 ? 16 : 10);
else if (wcsnicmp(paramName, L"/b:", 3) == 0)
*buttons = wcstoul(&argv[cnt][3], NULL, wcsnicmp(&argv[cnt][3], L"0x", 2) == 0 ? 16 : 10);
else
*message = argv[cnt];
}
return(*message != NULL);
}
Im gleichen Verzeichnis dann eine Batchdatei namens
build.cmd
anlegen und folgenden Code hineinkopieren:@echo off & setlocal
set "PrjName=ServiceMessage"
set "SourceFile=main"
set "PrjPath=%~dp0"
set "GCCPath=E:\CodeBlocksPortable\CodeBlocks\mingw32\bin"
cd /d "%GCCPath%"
gcc.exe -finput-charset=UTF-8 -g -O2 -I..\mingw\include -c "%PrjPath%\%SourceFile%.c" -o "%PrjPath%\%SourceFile%.o"
g++.exe -L..\mingw\lib -o "%PrjPath%\%PrjName%.exe" "%PrjPath%\%SourceFile%.o" -s -municode -static-libgcc -lkernel32 -lwtsapi32
gcc.exe
gespeichert ist. Durch Start der Batchdatei wird der obige C-Quelltext übersetzt. Die erstellte EXE-Datei wird im gleichen Verzeichnis wie die build.cmd
abgelegt.Gruß
Friemler
[EDIT]
Der Quellcode und das Build-Script erzeugen jetzt ein Unicode-fähiges Programm.
[/EDIT]