Comment trouver ma "description de l'ordinateur" dans une application Java sous Windows et/ou Mac?


, j'ai eu du mal à trouver la "description" de l'ordinateur sur lequel mon application Java est en cours d'exécution.

Ce que je recherche, c'est le nom utilisé pour DNS lors de la publicité de mon ordinateur sur le réseau local ("iMac Mattijs" dans les captures d'écran ci-dessous).

Sous Windows XP, ce nom peut être trouvé ici: Panneau de configuration -> Système -> Nom de l'ordinateur -> Description de l'ordinateur.

le texte d'alt

Sur Mac OS 10.6, ce nom peut être trouvé ici: Préférences système - > Partage - > Ordinateur Nom

le texte d'alt

Les méthodes ci-dessous ne fournissent pas le nom que je recherche. Jetez un oeil à ce code:

    System.out.println("COMPUTERNAME environment variable: " + System.getenv("COMPUTERNAME"));
    try { System.out.println("localhost name: " + InetAddress.getLocalHost().getHostName()); } 
    catch (UnknownHostException e1) {}

    try {
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface thisInterface = interfaces.nextElement();
            Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();

            System.out.println("* network interface: " + thisInterface.getDisplayName());
             while (addresses.hasMoreElements()) {
                 InetAddress address = addresses.nextElement();
                 System.out.println(" - address: " + address.getCanonicalHostName());
             }
        }           
    } catch (SocketException e) {}

Sous Windows, cela imprime:

COMPUTERNAME environment variable: ARTTECH-51CA5F5
localhost name: arttech-51ca5f5
* network interface: MS TCP Loopback interface
 - address: localhost
* network interface: NVIDIA nForce Networking Controller - Packet Scheduler Miniport
* network interface: Broadcom 802.11n Network Adapter - Packet Scheduler Miniport
 - address: arttech-51ca5f5.lan
* network interface: Bluetooth Device (Personal Area Network)

Sur Mac, je reçois:

COMPUTERNAME environment variable: null
localhost name: imac-mattijs.lan 
* network interface: en1
 - address: imac-mattijs.lan
 - address: imac-mattijs.local
* network interface: lo0
 - address: localhost
 - address: fe80:0:0:0:0:0:0:1%1
 - address: localhost

Mais je cherche la chaîne complète "iMac Mattijs".

Tous les indices seraient les bienvenus!

Merci, Mattijs

Author: Mattijs, 2010-10-14

10 answers

Mac OS X stocke le nom de l'ordinateur dans le magasin dynamique de configuration du système. L'interface standard à cela est via le cadre de configuration du système. L'outil de ligne de commande exerçant cette API est scutil:

$ scutil --get computerName
Hermes is awesome!

(J'ai temporairement changé le nom de mon ordinateur en quelque chose avec des espaces et de la ponctuation afin qu'il soit facilement reconnaissable du nom d'hôte, qui dans ce cas serait quelque chose comme hermes-is-awesome.local.)

Vous pouvez interfacer avec cela assez facilement en utilisant JNI:

class SCDynamicStore {
  public native String copyComputerName();
  static {
    System.loadLibrary("SCDynamicStore");
  }
}

class HostnameSC {
  public static void
  main(String[] args) {
    SCDynamicStore store = new SCDynamicStore();
    String computerName = store.copyComputerName();
    System.out.format("computer name: %s\n", computerName);
  }
}

Maintenant javac FILE.java, puis javah SCDynamicStore. Cela produit SCDynamicStore.h. Copiez ceci dans SCDynamicStore.c et modifiez-le pour lire:

#include "SCDynamicStore.h"
#include <SystemConfiguration/SystemConfiguration.h>

JNIEXPORT jstring JNICALL
Java_SCDynamicStore_copyComputerName(JNIEnv *env, jobject o)
{
  SCDynamicStoreRef store = NULL;
  CFStringRef computerName = NULL;
  CFStringEncoding UTF8 = kCFStringEncodingUTF8;
  CFIndex length;
  Boolean ok;
  jstring computerNameString = NULL;
  CFStringRef process = CFSTR("com.me.jni.SCDynamicStore");

  store = SCDynamicStoreCreate(NULL, process, NULL/*callout*/, NULL/*ctx*/);
  if (!store) {
    fprintf(stderr, "failed to get store\n");
    goto CantCreateStore;
  }

  computerName = SCDynamicStoreCopyComputerName(store, NULL);
  if (!computerName) {
    fprintf(stderr, "failed to copy computer name\n");
    goto CantCopyName;
  }

  length = CFStringGetLength(computerName);
  length = CFStringGetMaximumSizeForEncoding(length, UTF8);
  {
    char utf8[length];
    if (!CFStringGetCString(computerName, utf8, sizeof(utf8), UTF8)) {
      fprintf(stderr, "failed to convert to utf8\n");
      goto CantConvert;
    }
    computerNameString = (*env)->NewStringUTF(env, utf8);
  }

CantConvert:
  CFRelease(computerName);
CantCopyName:
  CFRelease(store), store = NULL;
CantCreateStore:
  return computerNameString;
}

(Vous pouvez simplifier le code en utilisant le pontage sans frais Obj-C et en tirant parti de -[NSString UTF8String]. Il peut être souhaitable de lancer une exception au lieu de simplement renvoyer NULL dans certains cas d'erreur.)

Vous pouvez ensuite compiler ceci en utilisant clang -shared -I/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Headers/ -framework CoreFoundation -framework SystemConfiguration SCDynamicStore.c -o libSCDynamicStore.dylib.

Maintenant, à condition que libSCDynamicStore.dylib soit le long de LD_LIBRARY_PATH, ce qu'il sera quand il sera dans le répertoire courant, vous pouvez exécuter l'application:

$ java HostnameSC
computer name: Hermes is awesome!
 3
Author: Jeremy W. Sherman, 2010-10-25 17:46:47

Voici ce que j'ai trouvé sur quelques expériences. La description de l'ordinateur est stockée dans la clé de registre

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\srvcomment

Donc, si nous avons une API que nous pouvons utiliser pour obtenir les valeurs de clé reg, nous pouvons le découvrir.

A également trouvé le lien suivant qui donne une bonne classe pour interroger les valeurs de clé reg:

Http://www.rgagnon.com/javadetails/java-0630.html

Et, En utilisant la classe WinRegistry donnée sur le site ci-dessus, j'ai pu trouver avec succès la description de l'ordinateur en utilisant le code:

String computerName = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\services\\LanmanServer\\Parameters", "srvcomment");
 4
Author: Balaram, 2010-10-23 17:07:20

Vous devez savoir qu'un seul ordinateur peut avoir plusieurs noms DNS.

Essayez ceci pour obtenir un nom:

  • Appel de java.net.NetworkInterface.getNetworkInterfaces() pour obtenir toutes les interfaces réseau;
  • Pour chaque NetworkInterface retourné, appelez {[2] } pour obtenir toutes les adresses IP d'une interface;
  • Pour chaque adresse IP renvoyée, appelez {[3] } pour obtenir le nom d'hôte associé;
  • Choisissez l'un des noms d'hôte.
 3
Author: Steve Emmerson, 2010-10-14 18:50:41

Je ne pense pas qu'il soit possible d'obtenir cela sans devenir natif. Si vous pouvez trouver une bibliothèque java qui vous donne accès à WMI, vous pouvez l'obtenir à partir de l'objet Win32_OperatingSystem dans la description du champ.

Googler donne quelques options probables;

Http://henryranch.net/software/jwmi-query-windows-wmi-from-java/
Très simple (et gratuit) si un peu hacky. Semble fonctionner en écrivant .scripts vbs vers un répertoire temporaire et en les appelant avec Runtime.getRuntime().exec() et cscript.EXE.

Https://com4j.dev.java.net/

Http://sourceforge.net/projects/jacob-project/
Java COM pont.

Je pense que la JVM Microsoft contient des bits natifs qui peuvent également aider.

 3
Author: Qwerky, 2010-10-20 14:11:03
  1. Obtenir com4j (lien de téléchargement direct) qui est une bibliothèque Java pour faire des appels à COM.

  2. Décompressez et dans l'exemple de dossier vous trouvera un WMI échantillon.

  3. Changer le principal.java et vous devriez être en jeu.

    
    package wmi;

    import com4j.Com4jObject; 
    import wmi.events.ISWbemSinkEvents; 

    public class Main {
        public static void main(String[] args) throws Exception {
            System.out.println("Connecting to WMI repository");
            ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
            ISWbemServices wbemServices = 
                    wbemLocator.connectServer(
                       "localhost","Root\\CIMv2","","","","",
                       0,null);

            System.out.println("connected");
            {
                System.out.println("Query Computer Description");
                ISWbemObjectSet result = wbemServices.execQuery(
                        "Select Description from Win32_OperatingSystem",
                          "WQL",48,null);
                for( Com4jObject obj : result ) {
                    ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
                    System.out.println(wo.getObjectText_(0));
                }
            }
        }
    }

 3
Author: renick, 2010-10-24 19:01:12

Que diriez-vous d'utiliser InetAddress.getHostName()?

System.out.println(
 "Name: " + java.net.InetAddress.getLocalHost().getHostName() );

Edit: Donc la réponse ci-dessus n'est évidemment pas ce que vous vouliez. Cependant... Le projetMAST fournit une méthode pour récupérer la description de l'ordinateur. Voir SysUtils.getComputerDescription(). Cette méthode est spécifique au système d'exploitation. La page d'accueil du projet indique qu'une version OSX est en préparation.

 2
Author: Andy, 2010-10-18 21:45:11

Êtes-vous sûr que vous n'êtes pas juste après la variable d'environnement COMPUTERNAME, ce que vous voyez dans cette fenêtre du panneau de configuration?

 1
Author: Michael Goldshteyn, 2010-10-14 14:45:32

Nom d'ordinateur " pur " pour MAC:

private static String getComputerName() {
            String s = "";
            try {
                Process proc = Runtime.getRuntime().exec("scutil --get ComputerName");
                InputStream in = proc.getInputStream();
                int b;
                while ( (b = in.read()) >= 0) {
                    s += (char)b;
                }
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
 1
Author: paulo roberto medeiros, 2012-02-27 23:15:41

Cette description/Nom de l'ordinateur se trouve être le nom d'hôte de l'hôte local. vous pouvez vérifier cela en vérifiant votre invite de terminal, qui affiche généralement ComputerName:CurrentDirectory User$ correspondant à une invite bash par défaut export PS1="\u@\h\w: "

Donc, en utilisant:

try { 
     InetAddress addr = InetAddress.getLocalHost();

     // Get hostname 
     String hostname = addr.getHostName();
} catch (UnknownHostException e) { } 

Vous devriez pouvoir obtenir le nom localhost comme vous le souhaitez. J'espère que cette aide.

Réf:

`

 0
Author: posdef, 2010-10-18 16:57:22

D'accord, j'ai trouvé un moyen de le faire moi-même, mais uniquement sur Mac OS. La prime est toujours ouverte aux personnes qui peuvent trouver un moyen de répondre à ma question sur Windows.

L'Exécution de cette application renvoie Computer Description: iMac Mattijs

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;

import com.apple.dnssd.*;

/**
 * Example of finding your computer description. Tested on Mac OS 10.6, Java 1.6
 * 
 * Note: make sure you're not compiling with JavaSE-1.6 but with JVM 1.6.0 (MacOS X Default), otherwise access to DNSSD libraries will be restricted.
 * 
 * @author mattijskneppers
 */

public class DescriptionFinder implements BrowseListener, ResolveListener {
    InetAddress local = null;
    HashMap<DNSSDService, String> fileSharingNameMap = new HashMap<DNSSDService, String>();

    public static void main(String[] args) {
        new DescriptionFinder();
    }   

    public DescriptionFinder() {
        try { local = InetAddress.getLocalHost(); } catch (UnknownHostException e) { System.out.println("Error, couldn't resolve local host"); }

        try {
            DNSSD.browse("_afpovertcp._tcp", this);
        } catch (DNSSDException e) {
            System.out.println("DeviceFinder: problem browsing for new file sharing");
            e.printStackTrace();
        }       
    }

    @Override
    public void operationFailed(DNSSDService arg0, int arg1) {}

    @Override
    public void serviceResolved(DNSSDService resolver, int flags, int ifIndex, String fullName, String hostName, int port, TXTRecord txtRecord) {
        InetAddress[] addresses = null;
        try {
            addresses = InetAddress.getAllByName(hostName);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        InetAddress ip = null;
        for (InetAddress address : addresses) {
            if (!address.isLinkLocalAddress()) {
                ip = address;
                break;
            }
        }

        String fileSharingName = fileSharingNameMap.get(resolver);
        if (fileSharingName != null) {
            if (ip.equals(local)) {
                System.out.println("Computer Description: " + fileSharingName);
            }
        }       
    }

    @Override
    public void serviceFound(DNSSDService service, int flags, int ifIndex, String serviceName, String regType, String domain) {
        //System.out.println("found file sharing: " + serviceName + ", domain: " + domain + ", regType: " + regType + ", flags: " + flags);
        try {
            DNSSDService resolver = DNSSD.resolve(flags, ifIndex, serviceName, regType, domain, this);
            fileSharingNameMap.put(resolver, serviceName);
        } catch (DNSSDException e) {
            System.out.println("DeviceFinder: problem resolving new filesharing device");
            e.printStackTrace();
        }           
    }

    @Override
    public void serviceLost(DNSSDService service, int flags, int ifIndex, String serviceName, String regType, String domain) {}
}
 0
Author: Mattijs, 2010-10-20 13:05:55