Serviço Windows: Posso configurar o diretório de trabalho atual?

11

Por padrão, os serviços do Windows iniciam no diretório sytem32 (geralmente C:\WINDOWS\system32).

Existe uma maneira de configurar um diretório de trabalho diferente? Estou pensando em algum parâmetro do registro abaixo HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Então - isso pode ser feito?

Tomalak
fonte
3
@Tomalak: É um serviço que você escreveu? Você pode fazê-lo através do código, mas não acho que exista um caminho através das configurações do serviço.
MattB
Não, não é um serviço que escrevi. Eu estava esperando alguma configuração de registro pouco conhecida aqui.
quer
Qual é o propósito de fazer isso?
user35115
@ user35115: Bem, para ser sincero… Ao rastrear um problema não relacionado ao procmon, notei que um determinado serviço pesado de E / S (um indexador de texto completo) verifica consistentemente seus próprios arquivos nos locais errados (bastante idiota). Inicia no system32, tenta mais alguns locais e, eventualmente, seu próprio diretório. Imaginei que, quando fosse executado em seu próprio diretório imediatamente, faria menos verificações desnecessárias de arquivos. Não que isso não funcionasse atualmente, mas me fez pensar se havia espaço para melhorias.
18710 Tomalak
1
@ user35115, Para evitar ter que alterar em massa as definições de configuração de um determinado aplicativo (por exemplo, Apache, etc), que são todos relativos ao diretório de trabalho.
Pacerier

Respostas:

5

Você pode usar a injeção de DLL para chamar SetCurrentDirectorydepois que o processo já foi iniciado. Isso exigiria a criação de um aplicativo injetor, além da DLL para injetar. Existem alguns tutoriais; provavelmente os dois melhores que eu encontrei são:

Você precisará de uma quantidade razoável de experiência em programação C ++ (e um ambiente de construção funcional) para superar isso.

No entanto, isso pressupõe que o serviço esteja olhando para o diretório atual. Outra possibilidade é que esteja usando %path%. Você diz que "começa em system32, tenta mais alguns locais e, eventualmente, seu próprio diretório", então isso me parece mais provável.

Compare os diretórios que você vê procmoncom o seu %path%. Se eles são o mesmo, considerar a modificação ou a SYSTEM %path%ou a %path%do usuário que executa o serviço, de modo que o diretório que você quer que ele procure é o primeiro.

Porém, acredito que Fred esteja certo - é improvável que você veja qualquer benefício significativo no desempenho fazendo isso, a menos que isso ocorra com muita frequência. Operações simples de abertura de arquivos não são particularmente caras, especialmente se for um caminho local e o arquivo não existir realmente.

fissão
fonte
A variável de ambiente PATH do sistema foi a primeira coisa que me veio à mente. Inserir o caminho do serviço no início da variável PATH, no entanto, terá um efeito negativo no desempenho de praticamente todos os outros aplicativos, portanto, não aconselho isso.
Marnix van Valen
Não tenho números concretos para apoiar isso de qualquer maneira, mas minha intuição me diz que nenhum ganho ou perda de desempenho prático ocorreria ao modificar o caminho. Este é um cenário bastante comum; ninguém culpa, digamos, as Ferramentas de Suporte do Windows, ou SQL Server, por impactar negativamente o desempenho do sistema quando ele modifica o caminho durante a instalação. Esta não é a primeira vez que vi alguém olhar para procmon e dizer "omg, veja todos esses acessos a arquivos!", Sem perceber que isso é típico para a maioria dos aplicativos.
fission
+1 para criatividade. :-) Entendo perfeitamente que essas operações de arquivo não afetam o desempenho de forma mensurável, por isso não vou me preocupar em escrever uma solução de injeção de DLL. Modificar %PATH%a conta de usuário sob a qual o serviço é executado é uma idéia decente.
Tomalak,
1
Criar um usuário especial para executar apenas este serviço e modificar o% PATH% para esse usuário é um ótimo caminho a percorrer. +1
Ensolarado
@ fission: Sim, isso significa que eu aceito sua resposta. ;) Não é o que eu esperava, mas é o mais próximo possível, eu acho.
quer
1

Como o MattB, não conheço nenhuma maneira de alterar o diretório de trabalho do serviço sem acesso ao código-fonte. Para esse cenário específico, é provável que as verificações extras do diretório não imponham muita atividade desnecessária em disco em relação à quantidade de E / S necessária para a operação de indexação de texto completo. Mesmo que você possa otimizá-los, o índice de texto completo será intensivo em disco pela natureza da fera.

Fred
fonte
1

Adicione um valor de string "AppDirectory" à Chave de parâmetros e defina o valor para o diretório de trabalho desejado.

Marca
fonte
Hum. Apenas testado, parece não funcionar (no Windows 7, usava o tipo de dados REG_EXPAND_SZ). Você pode confirmar novamente que isso realmente funciona para você, por favor?
Tomalak
Isso funciona ao usar srvany. Não tenho certeza sobre os serviços normais.
Konstantin Spirin
1

Faça isso na função principal do serviço:

  • Faça uma ligação para GetModuleFilename. Ele recuperará o nome do arquivo do módulo (o exe), incluindo o caminho, no formulário C:\path\to\exe\your_service.exe.
  • Use manipulações de string (talvez usando a std::stringfunção find_last_of()), para encontrar a última barra invertida. Tira / apara a string a partir daí para obter o caminho para o seu módulo e, portanto, o diretório do seu exe.
  • Faça uma chamada para a função SetCurrentDirectorye pronto!
uprightech
fonte
1
não se esqueça de passar null para o parâmetro HMODULE na chamada de função GetModuleFilename :)
uprightech