2010-03-09 12 views
10

Ho un C# exe che deve essere eseguito utilizzando WMI e accedere a una condivisione di rete. Tuttavia, quando accedo alla condivisione, ottengo un oggetto UnauthorizedAccessException. Se eseguo direttamente l'exe, la condivisione è accessibile. Sto usando lo stesso account utente in entrambi i casi.Autenticazione di rete durante l'esecuzione exe da WMI

Ci sono due parti per la mia applicazione, un client della GUI che gira su un PC locale e un processo di back-end che gira su un PC remoto. Quando il client deve connettersi al back-end, avvia il processo remoto utilizzando WMI (codice riprodotto di seguito). Il processo remoto fa una serie di cose, incluso l'accesso a una condivisione di rete usando Directory.GetDirectories() e riporta al client.

Quando il processo remoto viene avviato automaticamente dal client tramite WMI, non può accedere alla condivisione di rete. Tuttavia, se mi collego al computer remoto tramite Desktop remoto e avvio manualmente il processo di back-end, l'accesso alla condivisione di rete ha esito positivo.

L'utente specificato nella chiamata WMI e l'utente che ha effettuato l'accesso per la sessione di Desktop remoto sono gli stessi, quindi le autorizzazioni dovrebbero essere uguali, o no?

Vedo nella voce MSDN per Directory.Exists(), afferma "Il metodo Exists non esegue l'autenticazione di rete Se si interroga una condivisione di rete esistente senza essere pre-autenticata, il metodo Exists restituirà false." Presumo che questo sia correlato? Come posso garantire che l'utente sia autenticato correttamente in una sessione WMI?

ConnectionOptions opts = new ConnectionOptions(); 

opts.Username = username; 
opts.Password = password; 

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost)); 

ManagementScope scope = new ManagementScope(path, opts); 

scope.Connect(); 

ObjectGetOptions getOpts = new ObjectGetOptions(); 
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts)) 
{ 
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create"); 
    inParams["CommandLine"] = commandLine; 
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null); 
} 
+1

problema simile http://stackoverflow.com/questions/2291921/c-wmi-runs-an-exe-on-a-remote-computer-that-then-runs-another-exe-on-the- same-co/2291991 # 2291991 – lsalamon

+0

Grazie, la mia ricerca non l'aveva dimostrato. Avrò una lettura e vedere se aiuta. – Andy

+0

Ho aggiunto l'utente e ho fornito i permessi completi, ma non fa alcuna differenza :( – Andy

risposta

2

aver seguito il link suggerito da Isalamon sopra (grazie) ho seguito il consiglio di Jestro ed ho riscritto usando psexec.exe (che può essere scaricato da http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) invece di WMI. Sembra un po 'difficile da fare in questo modo, ma sembra funzionare.

nuovo codice per chi sta vivendo problemi simili:

Process proc = new Process(); 
proc.StartInfo.FileName = "PsExec.exe"; 
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}", 
             remoteHost, 
             domain, 
             username, 
             password, 
             commandLine); 
proc.StartInfo.CreateNoWindow = true; 
proc.StartInfo.UseShellExecute = false; 
proc.Start(); 
1

WMI solo utilizza la rappresentazione durante l'esecuzione del processo remoto, che non darvi rete di accesso. Se stai andando bene al di fuori del codice gestito, puoi semplicemente mappare un percorso UNC nel processo remoto. WMI ha iniziato a utilizzare qualsiasi credenziale tu voglia. Quindi, hai l'accesso alla rete che desideri. Uso NetUseAdd e NetUseDel da netapi32.dll per mappare il percorso UNC. Vedi http://pinvoke.net/ per i dettagli sull'utilizzo delle API.

0

È possibile scrivere tutti i comandi in un file batch sulla macchina remota che include l'utilizzo netto (non è necessario utilizzare una lettera di unità) per eseguire un'autenticazione. Funziona bene in questo modo. Sto ancora lavorando a un'alternativa.

+0

In realtà se si fa qualcosa come questo funzionerà pure, l'ho appena testato: – Will

+0

OOps qui è: inParams ["CommandLine"] = "cmd/c \" "+" net use \\\\ server \\ c $ password/utente: dominio \\ username && <\\ server \ share \ whatever.bat> "+" \ "> c: \\ temp \\ r_output.txt"; L'ho registrato per recuperare l'output più avanti nel mio codice. registra che esegue il file batch non comandi in esso. – Will

1

So che hai ha risolto utilizzando PSEXEC, che è un programma fantastico, ma se avete voglia di tornare a WMI, hai provato permettendo al seguente nei tuoi ConnectionOptions:

  • La bandiera AbilitaPrivilegi
  • impostando la rappresentazione su ImpersonationLevel.Rappresenta,

che fa la seguente:

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx

Penso che dovrebbero informare il WMI per consentire in realtà il programma di avere le credenziali corrette e quindi accedere alla condivisione di rete

Problemi correlati