2010-05-21 167 views
3

我試圖使用Redmon http://www.winimage.com/misc/redmon/將打印作業發送到自定義C#應用程序。 Redmon「運行」(實際上是打印後臺處理程序)作爲SYSTEM,但具有「運行身份用戶」選項以允許應用程序在打印作業的用戶下運行。問題是它似乎不加載用戶的環境。所以調用Path.GetTempPath()等函數指向\ windows \ temp而不是用戶的。此外,當試圖通過MAPI調用運行Outlook 2007+(添加附件)時,它會報告表單錯誤,因爲我認爲它是臨時文件夾位置。Redmon的用戶運行環境變量不加載用戶的環境變量

有沒有辦法在模擬應用程序中「重新加載」一個配置文件或至少讓你的環境變量?我迄今爲止唯一的想法是直接從註冊表重建變量,但是我想避免這種情況,因爲它是一種破解(避免實現細節和所有這些)。或者製作一個存根程序,讓Redmon調用這個存根程序,然後以完整的配置文件正確運行用戶身份。

任何其他物品或竅門?

回答

7

我最終找到了一種方法來加載用戶的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); 
} 
+0

更新的代碼使用ToInt64而不是64位系統的ToInt32(超過4gig ram?)。 http://stackoverflow.com/a/1866268報告說,它只會在32位系統上使用更多的開銷,但會起作用。 – Halfdone 2013-02-01 16:50:01