Comutadores CLI não são a única coisa que pode controlar o comportamento do Windows processos.
A chamada de processo via CLI e via Gerenciador de Tarefas é realmente muito diferente, e essa pegada pode ser usada de várias maneiras.
CWD (a resposta)
O motivo pelo qual o Explorer não inicia a barra de tarefas é que, quando executado a partir do CLI,
Seu diretório de trabalho é diferente quando é executado a partir do Gerenciador de Tarefas.
No GIF publicado, o CWD está definido como Z:\
, enquanto taskmgr
o define como
%código%. Sabe que deve configurá-lo para C:\Windows
, já que
C:\Windows
é a primeira pasta na variável de ambiente C:\Windows\
que
contém PATH
. Este detalhe é suficiente para fazer a diferença
simulando isso em explorer.exe
:
C:\> cd /d C:\windows
C:\windows> explorer
... restaura a barra de tarefas conforme o esperado.
cmd
A execução dos processos também pode ser controlada com um CreateProcess
Estrutura do Windows, que é usada pela função STARTUPINFO
do WinAPI, a principal
função para abrir novos processos no Windows.
Eu escrevi um programa para testar as diferenças entre CreateProcess
para programas
lançado pelo CMD e para programas lançados pelo Gerenciador de Tarefas:
#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;
}
Eu rapidamente cheguei com os seguintes resultados - executando o programa de teste através dos resultados do 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
enquanto o executa via STARTUPINFO
resulta nos seguintes resultados:
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
Podemos ver que eles obviamente diferem uns dos outros - por exemplo, CLI não quer que o programa mostre nenhuma janela, e o taskmgr fecha todos os padrões Alças de E / S. Qualquer programa pode usar essa informação para controlar seu comportamento - mesmo que não seja intuitivo para o usuário final, é totalmente possível.
taskmgr
A outra maneira padrão de executar processos é a função ShellExecute
do WinAPI.
De acordo com este post ,
ShellExecute
faz o seguinte:
- Determina o tipo de arquivo pesquisando no Registro do Windows.
- Enumera os comandos permitidos do shell (verbos).
- Recupera a linha de comando para o verbo especificado.
- Constrói as opções da linha de comando.
- Chama
ShellExecute
para iniciar o processo apontado pelo recuperado linha de comando.
Esta função é totalmente capaz de manipular parâmetros CLI do processo dado - na verdade, você pode tentar gerar um processo para um arquivo de texto ... e CreateProcess()
será executado o aplicativo padrão responsável por abrir arquivos de texto, usando parâmetros conforme instruído pelo Registro do Windows. Isso é o que o Gerenciador de Tarefas faz: se você tentar executar uma nova tarefa apontando para um arquivo de texto, descobrirá que ele deve abrir seu editor de texto padrão.