デフォルトでは、Windowsサービスはsytem32ディレクトリー(通常はC:\WINDOWS\system32
)で開始します。
別の作業ディレクトリを設定する方法はありますか?下にあるレジストリパラメータについて考えていますHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService
。
だから-これを行うことができますか?
デフォルトでは、Windowsサービスはsytem32ディレクトリー(通常はC:\WINDOWS\system32
)で開始します。
別の作業ディレクトリを設定する方法はありますか?下にあるレジストリパラメータについて考えていますHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService
。
だから-これを行うことができますか?
回答:
DLLインジェクションを使用してSetCurrentDirectory
、プロセスがすでに起動した後に呼び出すことができます。これには、インジェクターアプリケーションと、インジェクトするDLLをビルドする必要があります。いくつかのチュートリアルが存在します。おそらく私が見つけた2つの最高のものは次のとおりです。
それをやり遂げるには、C ++プログラミングの適切なバックグラウンド(および動作するビルド環境)が必要です。
ただし、これはサービスが現在のディレクトリを見ていることを前提としています。別の可能性は、それがを使用していること%path%
です。「から始まり、system32
さらにいくつかの場所を試し、最終的には独自のディレクトリを作る」と言っているので、これは私にはもっとありそうです。
に表示されるディレクトリをと比較procmon
します%path%
。それらが同じである場合は、サービスを実行しているユーザーのSYSTEM %path%
またはを変更して、%path%
検索するディレクトリが最初になるようにすることを検討してください。
ただし、Fredは正しいと思います。非常に頻繁に発生しない限り、これを実行してもパフォーマンスが大幅に向上することはほとんどありません。単純なファイルオープン操作は、特にローカルパスであり、ファイルが実際に存在しない場合は、それほどコストがかかりません。
%PATH%
ただし、サービスを実行するユーザーアカウントを変更することは、まともなアイデアです。
「AppDirectory」文字列値をパラメーターキーに追加し、その値を目的の作業ディレクトリに設定します。
srvany
ます。通常のサービスについてはわかりません。
これは、サービスのメイン関数内で行います。
GetModuleFilename
。これは、パスを含むモジュール(exe)ファイル名をの形式で取得しますC:\path\to\exe\your_service.exe
。std::string
function を使用find_last_of()
)を使用して、最後のバックスラッシュを見つけます。そこから文字列を削除/トリミングして、モジュールへのパスを取得します。つまり、exeのディレクトリを取得します。SetCurrentDirectory
を呼び出して、出来上がり!