Pregunta

Estoy intentando utilizar Redmon http://www.winimage.com/misc/redmon / para enviar trabajos de impresión a una aplicación personalizada C #. Redmon "corre" (en realidad la cola de impresión) como sistema, pero tiene la opción de Ejecutar como usuario para permitir que su aplicación se ejecute bajo el usuario que imprime el trabajo. El problema es que no parece cargar el entorno del usuario. Así que llamar a funciones como Path.GetTempPath () puntos a \ windows \ temp en lugar del usuario de. También cuando se intenta ejecutar Outlook 2007+ a través de las llamadas MAPI (para agregar datos adjuntos) se informa de errores debido a la forma, creo, la ubicación de la carpeta temp.

¿Hay una manera de "recarga" un perfil o al menos obtener su entorno vars dentro de la aplicación se hizo pasar? Las únicas ideas que he tenido hasta ahora es la reconstrucción de la vars directamente desde el registro, pero quieren evitar esto, ya que es alrededor de Hack (evitando los detalles de implementación y todo eso). O hacer un programa intermediario que las llamadas Redmon que luego adecuadamente usuario Ejecutar como con el perfil completo la aplicación personalizada.

Cualquier otro elemento o trucos?

¿Fue útil?

Solución

acabé encontrando una manera de cargar EnvironmentBlock del usuario, extraer cada variable y cargarlos en mi entorno existente. Sobre la base de código y las ideas de varias páginas:

Perdone mi código C #, ningún ajuste apreciado:

[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);
}

Otros consejos

Yo tenía el mismo problema en Windows 10.

Me di cuenta de que si el archivo .exe de la aplicación tiene la bandera "Ejecutar como administrador" conjunto, se ejecutará como usuario del sistema. Retirar esta bandera hizo que mi aplicación se ejecute con los privilegios del usuario y variables de entorno, que era lo que necesitaba.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top