2010-05-21 2 views
3

Redmon http://www.winimage.com/misc/redmon/을 사용하여 인쇄 작업을 사용자 지정 C# 응용 프로그램으로 보내려고합니다. Redmon은 SYSTEM (실제로 인쇄 스풀러)에서 "실행"되지만 작업을 인쇄 한 사용자로 실행되도록 응용 프로그램을 실행하는 옵션이 있습니다. 문제는 사용자 환경을로드하지 않는 것입니다. 따라서 Path.GetTempPath()와 같은 함수를 호출하면 사용자의 대신 \ windows \ temp를 가리 킵니다. 또한 MAPI 호출 (첨부 파일 추가)을 통해 Outlook 2007 이상을 실행하려고 시도하면 임시 폴더 위치로 인해 양식 오류가 발생한다고보고합니다.Redmon의 실행 사용자가 사용자의 환경 변수를로드하지 않음

프로필을 "새로 고침"하거나 가장 할 수있는 응용 프로그램 내에서 환경 변수를 구할 방법이 있습니까? 내가 지금까지 가지고있는 유일한 아이디어는 레지스트리에서 직접 vars를 재구성하는 것이지만, 해킹 (구현 세부 사항 및 모든 것을 피하는)이므로이 문제를 피하고자한다. 또는 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 대신 (4GB RAM 이상)? http://stackoverflow.com/a/1866268은 32 비트 시스템에서 더 많은 오버 헤드를 사용하지만 작동 할 것이라고보고합니다. – Halfdone