3つのドメイン全体でさまざまな管理タスクを実行するためにC#および.NET3.5で開発されたWindowsサービスがあります。このサービスが実行していることに必要な権限/権限を持つ管理者アカウントを各ドメインに持っています。
すべてのADインタラクションについて、ドメインの正しいユーザー名/パスワードを使用してADにバインドでき、すべて問題ありません。ただし、作業を実行するために外部プロセス(robocopy)を起動する必要があり、.NET3.5でこれを実行するためのコード例はどこにも見つかりません。
私がする必要があるのは、非表示のウィンドウで代替クレデンシャルを使用してrobocopyを起動し、標準出力をキャプチャして実際に行われたことのログを取得し、終了コードをキャプチャして成功したかどうかを確認することです。
System.Diagnostics.Processオブジェクトを拡張し、Win32API関数CreateProcessAsUserWを呼び出すK.Scott Allenのブログ(適切なコードリストについては、最後のいくつかのコメントを参照)から古い.NET1.1コードを見つけました。ただし、.NET 2.0でのAPIの変更により、コードは機能しません。参照されているブログの最後のコメントのコードスニペットを使用して、リフレクションを使用してProcessオブジェクトのプライベートSetProcessHandle関数を呼び出すと、プロセスを操作しようとすると(プロセスを強制終了するか、終了コードを取得するため)、AccessDeniedエラーが発生します。
誰かがこれを達成する方法の良い例を持っていますか?
編集:組み込みの.NETProcessおよびProcessStartInfoAPIを使用すると、代替の資格情報を指定できますが、指定すると、Windowsサービスとして実行すると失敗する表示ウィンドウを作成する必要があります(CreateNoWindowまたはWindowStyle Hiddenを指定した場合でも)。したがって、これらはこのアプリケーションのオプションではありません。外部プロセスが起動されると、偽装されたクレデンシャルではなく、親プロセスのクレデンシャルが使用されるため、偽装も機能しません。
解決策:Reedが以下で指摘しているように、Win32API関数の1つを使用してP/ Invokeを使用すると、これを実現できます。コマンドラインでユーザー名/パスワードを指定できるRunProcessと呼ばれる古いフリーウェアのNT4ユーティリティを使用して、少し異なるルートをたどることになりました。Vistaおよび2k3で動作し、ローカルシステムとして実行されているWindowsサービスによって起動されたときにも正しく動作しました。