Выполнение процесса в Windows 7 Welcome Screen

Таким образом, вот совок:

Я записал крошечное приложение C# некоторое время назад, которое отображает имя хоста, IP-адрес, изображенную дату, состояние оттепели (мы используем DeepFreeze), текущий домен и текущая дата / время, для отображения на экране приветствия наших машин лаборатории Windows 7. Это должно было заменить наш предыдущий блок информации, который был установлен статически при запуске и на самом деле встроенном тексте в фон с чем-то немного более динамическим и функциональным. Приложение использует Таймер для обновления IP-адреса, состояния холодильника и часов каждую секунду, и это проверяет, чтобы видеть, вошел ли пользователь в систему и уничтожает себя, когда это обнаруживает такое условие.

Если мы просто выполняем его, с помощью нашего сценария запуска (набор через групповую политику), это содержит открытый сценарий, и машина никогда не добирается до приглашения ко входу в систему. Если мы используем что-то как запуск или команды cmd для начинания его под отдельной оболочкой/процессом, это работает до концов сценария запуска, в которых Windows точки, кажется, очищает любого и все дочерние процессы сценария. Мы в настоящее время можем обойти то использование psexec -s -d -i -x для исчерпывания его который позволяет ему сохраниться, после, сценарий запуска завершается, но может быть невероятно медленным, добавив где угодно между 5 секундами и более чем минутой к нашему времени запуска.

Мы экспериментировали с использованием другого приложения C# для запуска процесса, через класс Процесса, использование Вызовов WMI (Win32_Process и Win32_ProcessStartup) с различными флагами запуска, и т.д., но всем концом с тем же результатом окончания сценария и информационного уничтожаемого процесса блока. Я переделал перезапись приложения как услуга, но сервисы никогда не разрабатывались для взаимодействия с рабочим столом, уже не говоря об окне входа в систему, и получение вещей, работающих в правильном контексте никогда действительно, казалось, удалось.

Таким образом для вопроса: у кого-либо есть хороший способ выполнить это? Запустите задачу так, чтобы это было бы независимо от сценария запуска и выполнения сверху экрана приветствия?

11
задан peelman 18 June 2010 в 13:50
поделиться

3 ответа

Это можно сделать с помощью множества вызовов Win32 API. Мне удалось получить программу с графическим интерфейсом пользователя на рабочем столе Winlogon (прежде чем кто-нибудь спросит, это не интерактивный графический интерфейс). В основном вам нужно запустить процесс загрузчика как SYSTEM, который затем запустит новый процесс. Поскольку вы, скорее всего, хотите, чтобы этот процесс запускался при запуске, вы можете либо использовать планировщик задач, чтобы запустить загрузчик как СИСТЕМУ, либо вы можете использовать службу, чтобы сделать то же самое. В настоящее время я использую службу, но я попытался использовать планировщик задач, и он отлично сработал.

Краткое описание:

  1. Захватите процесс Winlogon.exe (как процесс)
  2. Получите токен winlogon, используя OpenProcessToken, используя .handle процесса
  3. Создайте новый токен и скопируйте токен winlogon в it
  4. Повышение привилегий токена
  5. Создайте процесс, используя CreateProcessAsUser, убедившись, что для lpDesktop установлено значение «Winsta0 \ Winlogon» и используя созданный вами токен.

Пример кода:

        // grab the winlogon process
        Process winLogon = null;
        foreach (Process p in Process.GetProcesses()) {
            if (p.ProcessName.Contains("winlogon")) {
                winLogon = p;
                break;
            }
        }
        // grab the winlogon's token
        IntPtr userToken = IntPtr.Zero;
        if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out userToken)) {
            log("ERROR: OpenProcessToken returned false - " + Marshal.GetLastWin32Error());
        }

        // create a new token
        IntPtr newToken = IntPtr.Zero;
        SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES();
        tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes);
        SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
        threadAttributes.nLength = Marshal.SizeOf(threadAttributes);
        // duplicate the winlogon token to the new token
        if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
            TOKEN_TYPE.TokenImpersonation, out newToken)) {
            log("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error());
        }
        TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES();
        tokPrivs.PrivilegeCount = 1;
        LUID seDebugNameValue = new LUID();
        if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out seDebugNameValue)) {
            log("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error());
        }
        tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1];
        tokPrivs.Privileges[0].Luid = seDebugNameValue;
        tokPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        // escalate the new token's privileges
        if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero)) {
            log("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error());
        }
        PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        STARTUPINFO si = new STARTUPINFO();
        si.cb = Marshal.SizeOf(si);
        si.lpDesktop = "Winsta0\\Winlogon";
        // start the process using the new token
        if (!CreateProcessAsUser(newToken, process, process, ref tokenAttributes, ref threadAttributes,
            true, (uint)CreateProcessFlags.CREATE_NEW_CONSOLE | (uint)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero,
            logInfoDir, ref si, out pi)) {
            log("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error());
        }

        Process _p = Process.GetProcessById(pi.dwProcessId);
        if (_p != null) {
            log("Process " + _p.Id + " Name " + _p.ProcessName);
        } else {
            log("Process not found");
        }
12
ответ дан 3 December 2019 в 04:12
поделиться

Я думаю, вы справитесь, но это довольно сложно. Интерактивные приложения обычно не запускаются на экране приветствия. На высоком уровне вам необходимо:

  • Создать службу Windows, которая запускается автоматически
  • Использовать службу Windows для создания другого процесса в текущем сеансе и на рабочем столе (с помощью методов Win32 WTSGetActiveConsoleSessionId и OpenInputDesktop )

Я написал приложение, которое может в некоторой степени взаимодействовать с экраном входа в систему, но не отображает никакого пользовательского интерфейса. Вероятно, это можно сделать, но, возможно, потребуется еще больше усилий.

Примечание. Я обнаружил, что не смог получить результаты из OpenInputDesktop из моей службы Windows. Вместо этого мне пришлось позвонить в другой процесс и уведомить службу о перезапуске процесса на правильном рабочем столе.

Надеюсь, это поможет вам хотя бы начать работу. Удачи!

1
ответ дан 3 December 2019 в 04:12
поделиться

Это один из тех вопросов: «Вам действительно нужна веская причина для этого». Microsoft очень старается заблокировать приложения, запущенные на экране запуска - каждый бит кода в Windows, который взаимодействует с экраном входа в систему, очень тщательно проверяется, потому что последствия для безопасности ошибки в коде, запущенном на экране входа в систему, ужасны - если вы напортачите. даже немного, вы позволите вредоносному ПО проникнуть на компьютер.

Почему вы хотите запускать свою программу на экране входа в систему? Может быть, есть задокументированный способ сделать это не столь рискованно.

6
ответ дан 3 December 2019 в 04:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: