3

我正在尝试使用 Redmon http://www.winimage.com/misc/redmon/将打印作业发送到自定义 C# 应用程序。Redmon 作为 SYSTEM “运行”(实际上是 Print Spooler),但有一个以用户身份运行的选项,以允许您的应用程序在打印作业的用户下运行。问题是它似乎没有加载用户的环境。所以像 Path.GetTempPath() 这样的调用函数指向 \windows\temp 而不是用户的。此外,当尝试通过 MAPI 调用(添加附件)运行 Outlook 2007+ 时,它会报告由于临时文件夹位置而导致的表单错误。

有没有办法“重新加载”配置文件或至少在模拟应用程序中获取您的环境变量?到目前为止,我唯一的想法是直接从注册表重建 var,但我想避免这种情况,因为它是一个 hack(避免实现细节等等)。或者制作一个 Redmon 调用的存根程序,然后使用完整的自定义应用程序以用户身份正确运行。

还有其他物品或技巧吗?

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 回答
1

我在 Windows 10 上遇到了同样的问题。

我注意到如果应用程序的 .exe 文件设置了“以管理员身份运行”标志,它将以系统用户身份运行。删除此标志使我的应用程序以用户的权限和环境变量运行,这正是我所需要的。

于 2018-06-20T14:27:28.497 回答