Quando um processo é iniciado, por padrão as variáveis de ambiente são copiadas do processo pai (que está fazendo a solicitação para criar o novo processo) para o recém criado processo.
Quando você usa o método Run
, a instância de explorer.exe
manipulando sua área de trabalho criará a instância cmd
, mas quando você usar o método de explorer
Por exemplo, filho de svchost.exe
(filho de services.exe
, filho de wininit.exe
) criará a instância cmd
.
Se as duas versões do explorador não tiverem os mesmos blocos de ambiente, as instâncias de cmd
não terão as mesmas variáveis.
Quando a configuração das variáveis de ambiente é alterada das propriedades do sistema, o sistema operacional enviará uma mensagem WM_SETTINGCHANGE
para todas as janelas superiores. A instância explorer
que manipula a área de trabalho a receberá e atualizará seu bloco de ambiente, mas a instância que está manipulando a navegação de arquivo (a que está sob svchost.exe
) não processa a mensagem (não, neste momento não sei por quê) e seu bloco de ambiente não é atualizado (tudo isso foi testado com ProcExp
do sysinternal verificando os ambientes de processos).
Como resolver? Eu não sei. Talvez (não, não testado, eu não tenho um compilador disponível agora, apenas uma ideia) em vez de usar um HWND_BROADCAST
para enviar a mensagem WM_SETTINGCHANGE
, uma mensagem direta para o processo do navegador de arquivos poderia resolvê-lo (ou não)
Como lidar com isso? Elimine a instância explorer
cujo processo pai é svchost.exe
. Quando um novo navegador de arquivos é solicitado, uma nova instância é iniciada com o bloco de ambiente correto.
Para uma abordagem aproximada, apenas para tentar executar a partir da linha de comando
wmic process where "name='explorer.exe' and CommandLine like '%/factory%'" call Terminate
para matar o navegador de arquivos. Quando um novo navegador de arquivos é solicitado, um novo processo será criado (agora com o ambiente atualizado) e as novas instâncias de cmd
verão as alterações.
Editado
Depois de alguns testes com um monitor de API, vi que o svchost.exe
está criando o processo explorer
por meio de uma chamada CreateProcessAsUserW
api. Nessa chamada, o argumento lpEnvironment
não é nulo (se for nulo, o ambiente é copiado de pai para filho), portanto, svchost.exe
está criando o ambiente para o novo processo. Mas qual fonte está sendo usada para criar o novo ambiente?
Portanto, altero diretamente a variável no registro ( regedit
) para garantir que nenhuma mensagem WM_SETTINGSCHANGE
seja enviada, anule o navegador de arquivos explorer
instance e crie as duas cmd
instances. O resultado é
-
Run
method: a instânciacmd
não vê as alterações. Como não havia nenhuma mensagem para o pai, seu ambiente não foi alterado e o novo processo iniciado herda a versão inalterada doexplorer.exe
que manipula a área de trabalho. -
Shift + Método de clique: as alterações no registro estão disponíveis.
Portanto, svchost.exe
está recuperando as informações do registro para criar um bloco de ambiente para passar para o processo recém-criado.