2010-01-18 13 views
22

Sto cercando di avviare un'applicazione .NET con un utente diverso da un servizio .NET. L'idea è di creare un'applicazione di hosting in modalità sandbox in Windows. Nel servizio, ho creato l'utente in modo programmatico in Windows, creare una cartella per quell'utente e scaricare l'host .exe da un server in quella cartella. Quindi eseguo l'host .exe utilizzando System.Diagnostics.Process. Ecco l'StartInfo per il processo:Problemi di autorizzazione all'avvio dell'app .NET dal servizio .NET come utente diverso?

_process = new Process 
{ 
    StartInfo = 
    { 
     Arguments = " -debug", 
     FileName = instanceDirectory + "host.exe", 
     WorkingDirectory = instanceDirectory, 
     UseShellExecute = false, 
     RedirectStandardError = true, 
     RedirectStandardOutput = true, 
     RedirectStandardInput = true, 
     UserName = Helpers.GetUserNameForInstance(_hostid), 
     Password = _hostpass, 
     Domain = "" 
    }, 
    EnableRaisingEvents = true 
}; 

Quando eseguo il servizio come un servizio, il processo si blocca istantaneamente con un codice di errore di -1.073,741502 millions. ma quando eseguo il servizio come lo stesso utente specificato nel servizio Windows ma interattivamente nella console, tutto funziona correttamente. Questo accade solo quando si esegue il servizio come servizio e non direttamente nella console.

Qualsiasi aiuto sarebbe MOLTO apprezzato. Questo è stato un mal di testa per un lungo tempo e questo è l'ultima risorsa :(

+0

hai testato lo stesso codice in esecuzione in un'applicazione console? –

+2

sì, tutto funziona bene in modalità standalone .. ha solo problemi di esecuzione come servizio. –

+1

Ciao, come dici tu, sembra un problema di autorizzazione perché viene eseguito quando non è un servizio. Questo link potrebbe aiutare: http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html – keyboardP

risposta

1

0xc0000142 (-1073741502) è STATUS_DLL_INIT_FAILED:.

inizializzare la libreria di collegamento dinamico [nome] non riuscita il processo è terminato in modo anomalo

.

Come indicato dal sito Web TenaciousImpy, è necessario fornire le autorizzazioni dell'account per la stazione della finestra e il desktop. Ma se il programma è interattivo, è necessario impostare anche l'ID di sessione del token di processo.

14

Sembra che utilizzando il new Process() con un nome utente e una password e la modalità di servizio "non calcola" :)

Citazione da MSDN:

È possibile modificare i parametri specificati nel Proprietà StartInfo su fino al momento in cui si chiama il metodo Start sul processo. Dopo aver avviato il processo , la modifica dei valori di StartInfo non influenza o riavvia il processo associato . Se si chiama il metodo Start (ProcessStartInfo) con il ProcessStartInfo .. ::. UserName e ProcessStartInfo .. ::. Password proprietà impostate, la funzione non gestita CreateProcessWithLogonW è chiamato, che inizia il processo in una nuova finestra anche se il valore della proprietà CreateNoWindow è true o il valore della proprietà WindowStyle è nascosto.

Inoltre, guardando la documentazione CreateProcessWithLogonW:

lpStartupInfo [in]

Un puntatore a una struttura STARTUPINFO.L'applicazione deve aggiungere l'autorizzazione per l'account utente specificato alla stazione specificata stazione e desktop, anche per WinSta0 \ Default.

Se il membro lpDesktop è NULL o una stringa vuota, il nuovo processo eredita la stazione desktop e la finestra del processo padre. L'applicazione deve aggiungere l'autorizzazione per l'account utente specificato alla workstation finestra ereditata e al desktop .

Non c'è lpDesktop in .NET StartupInfo, d'altra parte l'utente SERVICE non ha desktop, che potrebbe causare il tuo problema.

Per farla breve, cercano di impostare il LoadUserProfile per true per caricare le informazioni dell'utente dal Registro di sistema, o forse è necessario impostare la directory di lavoro, ecc

Per indagare ulteriormente, il tuo dovrebbe controllare il vostro ambiente e magari accedere ai file a cui si accede utilizzando FileMon.

5

Vorrei provare a creare il processo sotto il contesto rappresentato dall'utente appena creato come di seguito.

[DllImport("advapi32.DLL", SetLastError = true)] 
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public extern static bool CloseHandle(IntPtr handle); 

[DllImport("advapi32.DLL")] 
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); 

static void Main() 
{    
    IntPtr admin_token = new IntPtr(); 
    WindowsIdentity wid_admin = null; 
    WindowsImpersonationContext wic = null; 

    LogonUser("username", "domain", "password", 9, 3, out admin_token); 
    wid_admin = new WindowsIdentity(admin_token); 
    wic = wid_admin.Impersonate(); 

    _process = new Process 
    { 
     StartInfo = 
     { 
      Arguments = " -debug", 
      FileName = instanceDirectory + "host.exe", 
      WorkingDirectory = instanceDirectory, 
      UseShellExecute = false, 
      RedirectStandardError = true, 
      RedirectStandardOutput = true, 
      RedirectStandardInput = true, 
      UserName = Helpers.GetUserNameForInstance(_hostid), 
      Password = _hostpass, 
      Domain = "" 
     }, 
     EnableRaisingEvents = true 
    }; 

    if (wic != null) wic.Undo(); 
    CloseHandle(admin_token); 
} 
+0

Ho provato quello e non sembra aiutare. Facendo riferimento a ciò che Gyuri ha citato, sembra che l'utente debba avere il permesso di usare la window station e il desktop a cui appartiene il servizio. – jamessan

Problemi correlati