Запустить запуск из системы через выходы CreateProcessAsuser, не показывая пользовательский интерфейс или записывает журC#

Место общения программистов C#
Ответить
Anonymous
 Запустить запуск из системы через выходы CreateProcessAsuser, не показывая пользовательский интерфейс или записывает жур

Сообщение Anonymous »

У меня есть две небольшие программы .net 8: < /p>
  • Код: Выделить всё

    Launcher.exe
    -приложение консоли, работающее в сессии 0 в разделе «Система» (запускается с Psexec -s).
  • Код: Выделить всё

    PopupClient.exe
    - приложение Winforms, которое должно отображать BessolveBox на интерактивном рабочем столе.

Код: Выделить всё

Launcher
использует CreateProcessasuser для запуска PopupClient внутри сеанса активной консоли.
Вызов успешно (return Code non rue, getlasterror == 0), Process.getProcessbyId находит новую пид, но ничто никогда не появляется на экране пользователя, и HeleppersbyId сразу же. /> минимальное воспроизводство < /strong> < /p>
  • Создайте оба автономных, однолетных, win-x64 < /p>
    < /li>
    Скопировать оба exes в одну и ту же папку на целевой машине < /p>
    < /li> Приглашение: < /p>

    Код: Выделить всё

    psexec -s "C:\Temp\PopupTest\Launcher.exe"
    < /code>
    Консоль вывод: < /p>
     === Launcher (Session 0) ===
    Current session : 0
    Active console  : 1
    
    Launched PopupClient.exe PID 3656
    Launcher finished.
    
  • no [/b] messagebox не отображается, и файлы журналов не создаются popupclient
Вопросы

[*], хотя один и тот же EXE работает нормально, когда он дважды щелкнул интерактивно? Popupclient.exe .

Код: Выделить всё

Launcher
:

Код: Выделить всё

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

namespace Launcher
{
internal class Program
{
[DllImport("wtsapi32.dll", SetLastError = true)]
private static extern bool WTSQueryUserToken(uint sessionId, out IntPtr token);

[DllImport("kernel32.dll")]
private static extern uint WTSGetActiveConsoleSessionId();

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);

[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);

[StructLayout(LayoutKind.Sequential)]
private struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX, dwY, dwXSize, dwYSize;
public uint dwXCountChars, dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}

[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}

private static void Main()
{
Console.WriteLine("=== Launcher (Session 0) ===");
Console.WriteLine($"Current session : {Process.GetCurrentProcess().SessionId}");

uint activeSession = WTSGetActiveConsoleSessionId();

if (activeSession == 0xFFFFFFFF)
{
Console.WriteLine("No active console session.");
return;
}

Console.WriteLine($"Active console  : {activeSession}");

if (!WTSQueryUserToken(activeSession, out IntPtr hUserToken))
{
Console.WriteLine($"WTSQueryUserToken failed: {Marshal.GetLastWin32Error()}");
return;
}

if (!CreateEnvironmentBlock(out IntPtr hEnv, hUserToken, false))
{
Console.WriteLine($"CreateEnvironmentBlock failed: {Marshal.GetLastWin32Error()}");
CloseHandle(hUserToken);
return;
}

string clientPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PopupClient.exe");
if (!File.Exists(clientPath))
{
Console.WriteLine($"PopupClient.exe not found at:  {clientPath}");
CloseHandle(hUserToken);
return;
}

STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(typeof(STARTUPINFO));
si.lpDesktop = "winsta0\\default";

bool ok = CreateProcessAsUser(
hUserToken,
null,
$"\"{clientPath}\"",
IntPtr.Zero,
IntPtr.Zero,
false,
0x00000400, // CREATE_UNICODE_ENVIRONMENT
hEnv,
null,
ref si,
out PROCESS_INFORMATION pi);

if (ok)
{
Console.WriteLine($"Launched PopupClient.exe PID {pi.dwProcessId}");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
Console.WriteLine($"CreateProcessAsUser failed: {Marshal.GetLastWin32Error()}");
}

CloseHandle(hEnv);
CloseHandle(hUserToken);
Console.WriteLine("Launcher finished.");
}
}
}
< /code>
PopupClient
:

Код: Выделить всё

using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace PopupClient
{
internal static class Program
{
[STAThread]
static void Main()
{
try
{
string log = Path.Combine(Path.GetTempPath(), "popup_debug.txt");
File.WriteAllText(log,
$"PopupClient started at {DateTime.Now:u}\r\n" +
$"Session: {Process.GetCurrentProcess().SessionId}\r\n" +
$"User   : {Environment.UserName}\r\n");

ApplicationConfiguration.Initialize();
MessageBox.Show(
$"SUCCESS!\r\nPID: {Process.GetCurrentProcess().Id}\r\nSession: {Process.GetCurrentProcess().SessionId}\r\nTime: {DateTime.Now}",
"System → User Session Popup",
MessageBoxButtons.OK,
MessageBoxIcon.Information);

File.AppendAllText(log, "MessageBox closed gracefully.\r\n");
}
catch (Exception ex)
{
File.WriteAllText(Path.Combine(Path.GetTempPath(), "popup_crash.txt"), ex.ToString());
}
}
}
}
< /code>
What I have tried[/b]
[list]
Replaced PopupClient
с 5-строчной версией, которая только записывает файл.

Код: Выделить всё

dotnet publish -r win-x64 -c Release --self-contained true -p:PublishSingleFile=true
).
[/list]
Я ожидал, что после запуска.

Код: Выделить всё

PopupClient.exe
) запустится внутри сеанса Active Console (сеанс 1) и немедленно написать файл и/или показывать Bessagebox на рабочем столе пользователя.
Пока я имею:
  • подтвержденный запуск действительно успешно (non-rearocessasuser , getLor>, 0 getLOR>, 0 getLor>, 0 getLOR>, 0 getLOR>, 0 getLOR>, 0 getLOR>, 0 getLOR>, 0 getLOR. видно в диспетчере задач для второго или двух
  • Lerped PopupClient до одного файла. Popupclient.exe интерактивно в сеансе 1 работает отлично (файл написан и появляется Messagebox).


Подробнее здесь: https://stackoverflow.com/questions/797 ... without-sh
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»