2010-06-14 12 views
21

Sto provando a eseguire dinamicamente un .jar da un assembly C# (utilizzando Process.Start(info)). Ora, da un'applicazione console sono in grado di eseguire solo:Come determinare il percorso di installazione di Windows Java

ProcessStartInfo info = new ProcessStartInfo("java", "-jar somerandom.jar"); 

In un assieme, però, continuo a ricevere un Win32Exception di "Il sistema non riesce a trovare il file specificato" e deve cambiare la linea per il pieno percorso di Java in questo modo:

ProcessStartInfo info = new ProcessStartInfo("C:\\Program Files\\Java\\jre6\\bin\\java.exe", "-jar somerandom.jar"); 

Questo ovviamente non lo farà. Ho bisogno di un modo per determinare dinamicamente (ma in modo dichiarativo) il percorso installato di Java.

Ho iniziato a pensare al registro, ma quando sono arrivato ho notato che c'erano chiavi specifiche per le versioni e che non potevano nemmeno essere garantite come numeriche (ad es. "HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft \ Java Runtime Ambiente \ 1.6 "e" HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft \ Java Runtime Environment \ 1.6.0_20 ").

Quale sarebbe la soluzione "a lungo raggio" più affidabile per trovare il percorso java.exe più aggiornato da un'applicazione C#?

Grazie molto in anticipo.

- EDIT -

Grazie ad una combinazione di GenericTypeTea 's e Stephen Cleary' risposte s, ho risolto il problema con il seguente:

private String GetJavaInstallationPath() 
{ 
    String javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment"; 
    using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(javaKey)) 
    { 
     String currentVersion = baseKey.GetValue("CurrentVersion").ToString(); 
     using (var homeKey = baseKey.OpenSubKey(currentVersion)) 
      return homeKey.GetValue("JavaHome").ToString(); 
    } 
} 

risposta

24

È possibile farlo tramite il registro. Comunque stavi cercando nel posto sbagliato. Bussai insieme un esempio veloce per voi:

private string GetJavaInstallationPath() 
{ 
    string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME"); 
    if (!string.IsNullOrEmpty(environmentPath)) 
    { 
     return environmentPath; 
    } 

    string javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\"; 
    using (Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(javaKey)) 
    { 
     string currentVersion = rk.GetValue("CurrentVersion").ToString(); 
     using (Microsoft.Win32.RegistryKey key = rk.OpenSubKey(currentVersion)) 
     { 
      return key.GetValue("JavaHome").ToString(); 
     } 
    } 
} 

Poi da usare, basta effettuare le seguenti operazioni:

string installPath = GetJavaInstallationPath(); 
string filePath = System.IO.Path.Combine(installPath, "bin\\Java.exe"); 
if (System.IO.File.Exists(filePath)) 
{ 
    // We have a winner 
} 
+0

Questo sembra perfetto! Grazie per aver sottolineato che mi sono perso il 'CurrentVersion'. Continuo a ottenere NullRef su 'rk', però.; ( – Lance

+1

È una convenzione comune che l'utente possa sovrascrivere il percorso java "autodetected" con una variabile di ambiente chiamata "JAVA_HOME". Un programmatore dovrebbe rispettare hat e dare la precedenza alle variabili: string java_path = Environment.GetEnvironmentVariable ("JAVA_HOME") ?? GetJavaInstallationPath(); –

+0

@Lance: non sono un esperto di java, quindi questa è solo una supposizione migliore. Hai dato un'occhiata per vedere se la chiave è presente? @SchlaWiener - Aggiornamento della mia risposta per riflettere il tuo commento (credo) – GenericTypeTea

1

Per quanto ne so l'idea è che l'ultima versione di Java installata sul sistema è la prima trovata nella variabile d'ambiente PATH, quindi non dovresti aver bisogno di cercare alcuna chiave di registro, basta eseguire la cosa.

Prova:

ProcessStartInfo info = new ProcessStartInfo("java.exe", "-jar somerandom.jar"); 

Se non funziona assicurarsi java.exe si trova nel percorso e fatemi sapere.

+0

Sfortunatamente, no. Se controllo 'info.EnvironmentVariables [" path "]', non contiene Java. D'altra parte, se apro un prompt dei comandi, posso semplicemente '> java -jar somerandom.jar' tutto il giorno, quindi so che dovrebbe essere lì. – Lance

+0

È possibile verificare quale processo java.exe viene eseguito quando lo si esegue dal prompt dei comandi? – Grzenio

+0

@LanceMay e hai anche provato la versione con estensione dopo il nome del processo? – Grzenio

0

Basandosi sulla cima della @GenericTypeTea domanda - questo è un modo come controllare sia su x32/x64.

static string GetJavaInstallationPath() 
{ 
    string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME"); 
    if (!string.IsNullOrEmpty(environmentPath)) 
    { 
    return environmentPath; 
    } 

    const string JAVA_KEY = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\"; 

    var localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32); 
    using (var rk = localKey.OpenSubKey(JAVA_KEY)) 
    { 
    if (rk != null) 
    { 
     string currentVersion = rk.GetValue("CurrentVersion").ToString(); 
     using (var key = rk.OpenSubKey(currentVersion)) 
     { 
     return key.GetValue("JavaHome").ToString(); 
     } 
    } 
    } 

    localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); 
    using (var rk = localKey.OpenSubKey(JAVA_KEY)) 
    { 
    if (rk != null) 
    { 
     string currentVersion = rk.GetValue("CurrentVersion").ToString(); 
     using (var key = rk.OpenSubKey(currentVersion)) 
     { 
     return key.GetValue("JavaHome").ToString(); 
     } 
    } 
    } 

    return null; 
} 
+0

https://msdn.microsoft.com/en-us/library/dd411615(v=vs.110).aspx Nelle versioni a 64 bit di Windows, porzioni del registro sono memorizzate separatamente per 32-bit e 64- applicazioni bit. Esiste una visualizzazione a 32 bit per le applicazioni a 32 bit e una visualizzazione a 64 bit per le applicazioni a 64 bit. Se view è Registry64 ma la macchina remota esegue un sistema operativo a 32 bit, la chiave restituita utilizzerà la vista Registry32. – SimplyInk

+0

Pertanto, solo la chiamata per aprire la chiave dalla vista Registry64 è sufficiente per coprire entrambi i casi del sistema operativo a 32/64 bit. – SimplyInk

Problemi correlati