Итак, Windows Explorer снова обрушился на меня, и теперь моя панель задач исчезла. Но я знаю, что все, что мне нужно сделать, это снова запустить Explorer, и панель задач снова появится.

Если я запускаю Проводник через taskmgr , все работает - панель задач появится снова, как я и хотел.
Но иногда я пытаюсь запустить Explorer через cmd.exe . Причина, по которой я это делаю, не имеет значения.

Нету. Ничего не произошло. Он просто открывает "Библиотеки" в новом окне и не восстанавливает панель задач.

Вот описанное поведение, записанное на GIF. Я проверяю, что проводник не запущен, затем запускаю его через CLI, а после - через taskmgr . Обратите внимание, как выглядит панель задач (вверху экрана), только если я запускаю explorer через taskmgr .

Вот вопрос: почему и как это происходит? taskmgr позволяет мне запускать произвольные задачи, которые должны быть идентичны тем, что предлагает cmd . Если taskmgr проверит, если я попытаюсь запустить explorer и добавит некоторые загадочные параметры командной строки в таких случаях, это ничем не должно отличаться от моей попытки запустить Explorer через CLI. И все же каким-то образом Explorer знает, что восстанавливать панель задач можно только тогда, когда она запускается через taskmgr , поэтому в ее выполнении должно быть что-то другое. В этом случае, что отличается - это CLI-вызов или что-то еще полностью?

1 ответ1

1

Переключатели CLI - не единственное, что может контролировать поведение процессов Windows.

Вызов процесса через CLI и через диспетчер задач на самом деле сильно отличается, и этот след может быть использован несколькими способами.

CWD (ответ)

Причина, по которой Explorer не запускает панель задач, заключается в том, что при запуске из CLI его рабочий каталог отличается от того, когда он выполняется из диспетчера задач. В опубликованном GIF CWD установлен в Z:\ , в то время как taskmgr устанавливает в C:\Windows . Он знает, что ему следует установить его в C:\Windows , поскольку C:\Windows\ - это первая папка в переменной среды PATH которая содержит explorer.exe . Этой детали достаточно, чтобы изменить ситуацию - смоделируйте это в cmd:

C:\> cd /d C:\windows
C:\windows> explorer

... действительно восстанавливает панель задач, как и ожидалось.

CreateProcess

Выполнение процессов также можно контролировать с помощью структуры Windows STARTUPINFO , которая используется функцией CreateProcess WinAPI, основной функцией для открытия новых процессов в Windows.

Я написал программу для проверки различий между STARTUPINFO для программ, запускаемых CMD, и для программ, запускаемых диспетчером задач:

#include <stdio.h>
#include <Windows.h>

int main(int argc, char ** argv)
{
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    GetStartupInfo(&si);

    FILE *fp = fopen("Z:\\output.txt",  "a");
    if (!fp) {
        return 1;
    }
    fprintf(fp, "cb:              %08x\n", si.cb);
    fprintf(fp, "lpDesktop:       %s\n", si.lpDesktop);
    fprintf(fp, "dwX:             %d\n", si.dwX);
    fprintf(fp, "dwY:             %d\n", si.dwY);
    fprintf(fp, "dwXSize:         %d\n", si.dwXSize);
    fprintf(fp, "dwYSize:         %d\n", si.dwYSize);
    fprintf(fp, "dwXCountChars:   %d\n", si.dwXCountChars);
    fprintf(fp, "dwYCountChars:   %d\n", si.dwYCountChars);
    fprintf(fp, "dwFillAttribute: %d\n", si.dwFillAttribute);
    fprintf(fp, "dwFlags:         %d\n", si.dwFlags);
    fprintf(fp, "wShowWindow:     %d\n", si.wShowWindow);
    fprintf(fp, "hStdInput:       %08x\n", si.hStdInput);
    fprintf(fp, "hStdOutput:      %08x\n", si.hStdOutput);
    fprintf(fp, "hStdError:       %08x\n", si.hStdError);
    fclose(fp);

    return 0;
}

Я быстро получил следующие результаты - запуск тестовой программы через CMD приводит к следующим результатам:

cb:              00000044
lpDesktop:       Winsta0\Default
dwX:             0
dwY:             0
dwXSize:         0
dwYSize:         0
dwXCountChars:   0
dwYCountChars:   0
dwFillAttribute: 0
dwFlags:         256
wShowWindow:     0
hStdInput:       000001d8
hStdOutput:      000001dc
hStdError:       000001dc

при запуске через taskmgr получается следующее:

cb:              00000044
lpDesktop:       Winsta0\Default
dwX:             0
dwY:             0
dwXSize:         0
dwYSize:         0
dwXCountChars:   0
dwYCountChars:   0
dwFillAttribute: 0
dwFlags:         1
wShowWindow:     1
hStdInput:       ffffffff
hStdOutput:      ffffffff
hStdError:       ffffffff

Мы можем видеть, что они явно отличаются друг от друга - например, CLI не хочет, чтобы программа показывала какое-либо окно, и taskmgr закрывает все стандартные дескрипторы ввода / вывода. Любая программа может использовать эту информацию для управления своим поведением - даже если она не интуитивна для конечного пользователя, это вполне возможно.

ShellExecute

Другим стандартным способом запуска процессов является функция ShellExecute WinAPI. Согласно этому сообщению, ShellExecute делает следующее:

  1. Определяет тип файла путем поиска в реестре Windows.
  2. Перечисляет разрешенные команды оболочки (глаголы).
  3. Получает командную строку для указанного глагола.
  4. Создает ключи командной строки.
  5. Вызывает CreateProcess() для запуска процесса, на который указывает полученная командная строка.

Эта функция полностью способна манипулировать параметрами CLI данного процесса - фактически, вы можете попытаться порождать процесс для текстового файла ... и ShellExecute запустит приложение по умолчанию, отвечающее за открытие текстовых файлов, используя параметры в соответствии с инструкциями Windows Реестр. Вот что делает Task Manager: если вы пытаетесь запустить новую задачу, указывающую на текстовый файл, он обнаруживает, что должен открыть ваш текстовый редактор по умолчанию.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .