2010-06-14 3 views
21

J'essaie d'exécuter dynamiquement un .jar à partir d'un assemblage C# (en utilisant Process.Start(info)). Maintenant, à partir d'une application console je peux juste lancer:Comment déterminer l'emplacement d'installation de Windows Java

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

Dans un ensemble, cependant, je continue à obtenir un Win32Exception de « Le système ne peut pas trouver le fichier spécifié » et doivent changer la ligne à la pleine chemin de Java comme ça:

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

Cela ne va évidemment pas. J'ai besoin d'un moyen de déterminer dynamiquement (mais déclarativement) l'emplacement installé de Java. J'ai commencé à penser à regarder dans le registre, mais quand je suis arrivé là, j'ai remarqué qu'il y avait des clés spécifiques pour les versions et qu'elles ne pouvaient même pas être numériques (par exemple "HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft \ Java Runtime Environnement \ 1.6 "et" HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft \ Java Runtime Environment \ 1.6.0_20 ").

Quelle serait la solution «long-courrier» la plus fiable pour trouver le chemin java.exe le plus à jour à partir d'une application C#?

Merci beaucoup à l'avance.

- EDIT -

Merci à une combinaison de GenericTypeTea 's et Stephen Cleary' réponses s, j'ai résolu le problème avec les éléments suivants:

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

Répondre

24

Vous pouvez le faire via le registre. Vous cherchiez au mauvais endroit cependant. Je frappai ensemble un exemple rapide pour vous:

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

Puis l'utiliser, procédez comme suit:

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

Cela semble parfait! Merci de m'avoir fait remarquer que j'ai manqué le 'CurrentVersion'. Je continue d'obtenir NullRef sur 'rk', cependant.; ( – Lance

+1

Il est courant que l'utilisateur écrase le chemin java "autodétecté" avec une variable d'environnement appelée "JAVA_HOME" .Un programmeur doit respecter hat et lui donner la priorité: string java_path = Environment.GetEnvironmentVariable ("JAVA_HOME") ?? GetJavaInstallationPath(); –

+0

@Lance - Je ne suis pas un expert Java, donc c'est seulement une meilleure estimation.) Avez-vous jeté un oeil pour voir si la clé est là? @SchlaWiener - Mise à jour de ma réponse pour refléter votre commenter (je pense) – GenericTypeTea

1

Pour autant que je sais que l'idée est que la dernière version de Java installée sur le système est la première qui se trouve dans la variable d'environnement PATH, donc vous ne devriez pas avoir besoin de chercher des clés de registre, exécutez simplement la chose.

Essayez:

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

Si cela ne fonctionne pas assurez-vous que java.exe est dans votre chemin et laissez-moi savoir.

+0

Malheureusement, non. Si je consulte le 'info.EnvironmentVariables [" path "]', il ne contient pas Java. D'un autre côté, si j'ouvre une invite de commande, je peux juste '> java -jar somerandom.jar' toute la journée, donc je sais que c'est supposé être là. – Lance

+0

Pourriez-vous vérifier quel processus java.exe s'exécute lorsque vous l'exécutez à partir de l'invite de commande? – Grzenio

+0

@LanceMay, et avez-vous réellement essayé la version avec l'extension après le nom du processus? – Grzenio

0

bâtiment sur la question @GenericTypeTea - c'est un moyen comment vérifier à la fois sur 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 Sur les versions 64 bits de Windows, des parties du registre sont stockées séparément pour les versions 32 bits et 64 bits. applications peu. Il existe une vue 32 bits pour les applications 32 bits et une vue 64 bits pour les applications 64 bits. Si la vue est Registry64 mais que la machine distante exécute un système d'exploitation 32 bits, la clé retournée utilisera la vue Registry32. – SimplyInk

+0

Par conséquent, l'appel de la vue Registry64 suffit à couvrir les deux cas de système d'exploitation 32/64 bits. – SimplyInk