3

Redmon http://www.winimage.com/misc/redmon/を使用して印刷ジョブをカスタム C# アプリケーションに送信しようとしています。Redmon は SYSTEM として "実行" (実際には印刷スプーラー) しますが、ジョブを印刷したユーザーの下でアプリケーションを実行できるように、ユーザーとして実行するオプションがあります。問題は、ユーザーの環境をロードしていないように見えることです。そのため、Path.GetTempPath() などの関数を呼び出すと、ユーザーの代わりに \windows\temp がポイントされます。また、(添付ファイルを追加するために) MAPI 呼び出しを介して Outlook 2007+ を実行しようとすると、一時フォルダーの場所が原因でフォーム エラーが報告されます。

偽装アプリケーション内でプロファイルを「リロード」するか、少なくとも環境変数を取得する方法はありますか? 私がこれまでに持っていた唯一のアイデアは、変数をレジストリから直接再構築することですが、これはハックであるため(実装の詳細などを避けて)避けたいと思います。または、Redmon が呼び出すスタブ プログラムを作成し、カスタム アプリケーションのフル プロファイルで適切に Run As User を実行します。

他のアイテムやトリックはありますか?

4

2 に答える 2

8

ユーザーの EnvironmentBlock をロードし、各変数を抽出して既存の環境にロードする方法を見つけました。いくつかのページのコードとアイデアに基づいています:

私のC#コードを許してください。

[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit); 

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle); 
private const uint TOKEN_QUERY = 0x0008; 

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);

private static void ReloadEnviroVars()
{
  IntPtr hToken = IntPtr.Zero;
  IntPtr envBlock = IntPtr.Zero;

  //Load this user's environment variables
  OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, ref hToken);
  bool retVal = CreateEnvironmentBlock(ref envBlock, hToken, false);

  //Extract each environment variable from the envroblock and add it to
  // our running program's environment vars
  int offset = 0;
  while (true) {
    //EnviroBlock is an array of null-terminated unicode strings
    IntPtr ptr = new IntPtr(envBlock.ToInt64() + offset);
    string Enviro = Marshal.PtrToStringUni(ptr);
    offset += Encoding.Unicode.GetByteCount(Enviro) + 2;
    if (string.IsNullOrEmpty(Enviro))
      break;
    string EnviroKey = Enviro.Substring(0, Enviro.IndexOf("="));
    string EnviroValue = Enviro.Substring(Enviro.IndexOf("=") + 1,  Enviro.Length - 1 - Enviro.IndexOf("="));
    Environment.SetEnvironmentVariable(EnviroKey, EnviroValue);
  }

  CloseHandle(hToken);
}
于 2010-06-13T15:07:01.197 に答える