サービスの複数のインスタンスは必要ありません。問題の説明から、必要なのは、ユーザーになりすましてジョブを実行できる 1 つのサービスのようです。
これを行うには、サービスでホストされる COM オブジェクトを実装します。クライアント アプリケーション (エンド ユーザーが実行する) は、CLSID で CoCreateInstanceEx を呼び出します。これにより、COM オブジェクトの新しいインスタンスがサービス内に作成されます。次に、アプリケーションはインターフェイスの 1 つでメソッドを使用して、収集したユーザー資格情報を COM オブジェクトに渡すことができます (ただし、資格情報の収集には慎重になり、代わりにユーザー トークンを渡すことができるかどうかを確認します)。サービスのコンテキストで実行されている COM オブジェクトは、LogonUser() を呼び出してユーザーにログオンし、偽装することができるため、ユーザーに代わって何でも実行できます (ユーザーのローカル appdata フォルダーの検索など:-))。他の回答には、資格情報またはトークンを使用してユーザーを偽装するための適切なリンクがあります。
COM に慣れている場合は、オブジェクトの実行が COM によってシリアル化されないように、オブジェクトをマルチスレッド (MTA 内にある) として作成することをお勧めします。そうでない場合は、デフォルトのシングル スレッド モデルで十分です。
Visual Studio ATL ウィザードは、サービス内に存在する COM オブジェクトのスケルトンを生成できます。ATL を使用した Windows サービスの実装については、http: //msdn.microsoft.com/en-us/library/74y2334x (VS.80).aspx を参照してください。
COM をまったく知らない場合は、他の通信チャネルを使用して資格情報をサービスに渡すことができます。
いずれにせよ、サービスが資格情報を取得したら、ユーザーとして実行されているアプリケーションをブロックしないように、ユーザーに代わってすべての作業をバックグラウンド スレッドで実行する必要があります。