Windows-Environment-Variable per jRegistryKey anpassen

xjCoder

Aktives Mitglied
Hallo Leute,

heute möchte ich auch mal eine Frage (oder Problemchen) in die Runde stellen ;)

Ich schreibe an einem Programm, welches auch Einträge in die Windows-Registry macht.
Dies erledige ich mit der Library jRegistryKey.

Nun muss ich auch die Environment-Variable %Path% erweitern, was auch problemlos
erledigt wird, zumindest kann ich den neuen Wert per Regedit ansehen.
Leider werden die Anpassungen erst nach einem Neustart in die Systemumgebung übernommen,
ich benötige diese aber eigentlich bereits nach dem Einfügen in die Registry... ;-(

Soweit ich bis jetzt herausgefunden habe, scheint es notwendig zu sein über die Windows-API
ein WM_SETTINGCHANGE-"Event" auszulösen...

Ich habe auch eine Umsetzung für Java (JNA) gefunden klick aber leider bekomme ich es nicht
zum Laufen, da ich mich nicht wirklich mit der Windows-API oder JNI/JNA auskenne.

Hat vielleicht jemand Erfahrungen oder sogar eine Lösung um so ein WM_SETTINGCHANGE auszuführen?!
...oder bin ich vielleicht sogar völlig auf dem Holzweg?!
...ich bin für jeden Hinweis dankbar


Einen kleinen Beispiel-Code zu meinem Problemchen habe ich übrigens auch noch :oops:


Java:
import java.util.ArrayList;
import java.util.Iterator;

import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RegistryValue;
import ca.beq.util.win32.registry.RootKey;
import ca.beq.util.win32.registry.ValueType;


public class EnvironmentRegistryTest
{
  public static void main(String[] args)
  {
    String envVar = "Path";
    
    String addToEnvVar = "test01";
    
    String envNow = new W32RegistryUsage().getEnvironmentRegistryKeys(envVar);
    System.out.println(envNow);
    
    new W32RegistryUsage().writeEnvironmentRegistryKey(envVar, addToEnvVar + ";" + envNow);
    
    System.out.println(new W32RegistryUsage().getEnvironmentRegistryKeys("Path") );
    
  }
  
  
  static class W32RegistryUsage
  {
    private String dll = "c:\\TEMP\\jRegistryKey.dll";
    private String regenv = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
    
    
    boolean writeEnvironmentRegistryKey(String regkey, String regvalue)
    {
      RegistryKey.initialize(dll);
      
      RegistryKey key;
      RegistryValue keyVal;
      
      ArrayList<String> list = new ArrayList<String>();
      
      key = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE, regenv);
      
      if(key.exists())
      {
        if(key.hasValues())
        {
          Iterator i = key.values();
          
          while(i.hasNext()) 
          {
            keyVal = (RegistryValue)i.next();
            
            if( keyVal.getName().toString().trim().equals(regkey) )
            {
              keyVal.setData(regvalue);
              key.setValue(keyVal);
              return true;
            }
          }
          
          //wenn ich hier bin scheint der Schluessel nicht zu existieren
          RegistryValue val = new RegistryValue(regkey, ValueType.REG_EXPAND_SZ, regvalue);
          key.setValue(val);
          return true;
        }
      }
      
      return false;
    }
    
    
    String getEnvironmentRegistryKeys(String regkey)
    {
      RegistryKey.initialize(dll);
      
      RegistryKey key;
      RegistryValue keyVal;
      
      String regvalue = null;
      
      key = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE, regenv);
      if(key.exists())
      {
        if(key.hasValues())
        {
          Iterator i = key.values();
          
          while(i.hasNext()) 
          {
            keyVal = (RegistryValue)i.next();
            
            if(keyVal.getName().toUpperCase().trim().equals(regkey.toUpperCase()))
            {
              regvalue = keyVal.getStringValue();
            }
          }
        }
      }
      
      return regvalue;
    }
    
  }  
  
}
 

KrokoDiehl

Top Contributor
Hallo.
Also was man an Winapi-Funktion aufrufen muss, damit die neue Umgebung direkt aktiviert wird, das weiß ich nicht. Beim Aufbau der JNA-Anbindung könnte ich eher helfen ... wobei ich die JNA-Anleitung auch recht nutzbar finde.

Aber auch wenn du die Umgebungsänderung direkt "scharf" schalten kannst, wirkt sie sich nicht auf bereits laufende Anwendungen aus. Ich hoffe auf so etwas zielst du nicht ab?

[EDIT]JNA doch noch gefunden, ist hier ...[/EDIT]
 
Zuletzt bearbeitet:

xjCoder

Aktives Mitglied
Hi KrokoDiehl,

& Danke für Dein Interesse :)

Neee, es geht mir nicht um die laufenden Anwendungen,
sondern nur um nach der Anpassung gestartete Progs.

Die einfachste JNA-Anbindung (noch mit 3.2.7) mit
einer LockWorkStation()-Methode habe ich bereits
beispielhaft mit eingebaut, so daß ich davon ausgehe,
daß ich eine bestehende Verbindung aufbauen kann.

Nur die Aktivierung des Environments will einfach nicht... ;(
 

KrokoDiehl

Top Contributor
Okay... der von dir gepostete Link beschreibt doch genau dein Thema oder? Dein Problem ist also dass das dort beschriebene bei dir nicht funktioniert? Klappen die Windows-Aufrufe nicht oder geschieht einfach nichts?
(Hier MSDN zu SendMessageTimeout()).

Wenn du C++ bei dir Programmieren kannst, kannst du zum Prüfen ja dort mal ein kleines Testprogramm machen und schauen ob die Funktionalität überhaupt das tut, was du möchtest.

Ansonsten ...wir hatten mal Probleme bei 32bit-Anwendungen, 64bit-Windows und der Registry, weil 32bit eine andere LOCAL_MASCHINE-Registry verwenden (HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node). Am Ende wird nur das "falsche" aktualisiert?
 

xjCoder

Aktives Mitglied
...also es handelt sich um ein 32Bit System (Win XP).

Der Link zeigt auch ein entsprechendes Beispiel, welches nicht ganz 1:1 genutzt werden kann da
die Zeile
Code:
hwnd.setPointer(new IntByReference(User32.HWND_BROADCAST).getPointer (0));
nicht mit getPointer(0) ausgeführt werden kann.
Die Ausführung gibt mir zumindest keine Fehlermeldung zurück (Code 0).

...aber dazu kommt mir noch eine kleine Idee - aber die kann ich erst morgen ausprobieren.

...mit C++ habe ich keine großen Erfahrungen, ob ich da einen Test zusammensetzen kann,
werde ich mir dann auch morgen mal ansehen.


Falls es noch ein paar gute Ideen gibt - gerne ;)

...ansonsten werde ich das Thema nun auf morgen vertagen.


Danke erstmal :toll:
 

KrokoDiehl

Top Contributor
Da mich das auch nun interessiert hat, habe ich es mal probiert und nach einigem Hin-und-her hinbekommen. Das mit dem HWND war tatsächlich der Knackpunkt... man muss 2x getPointer() aufrufen. Ein anderer war, dass man die ANSI- oder WIDECHAR-Variante der Winapi-Funktion nehmen muss. Habe mich für WIDE entschieden. Sonst kam bei mir immer ein "Funktion nicht gefunden". Ist bei dir aber vielleicht anders, sprich ggfs. mal das "W" am Funktionsnamen weglassen oder durch ein "A" ersetzen.
Von JNA habe ich das neuste vom zuletzt geposteten Link genommen.

Hier mein Code (funktionierte sogar bei Java 7, 64bit JRE, aber auch auf Java 6, 32bit):
Java:
// Die Benennung hier ist kein Musterbeispiel! :)
public final class Test {

    public static interface User32 extends Library {
        LRESULT SendMessageTimeoutW(HWND handle, long msg, long wp, String lp, long f, long to, DWORD_PTR p);
    }
    
    public static interface Kernel32 extends Library {
        int GetLastError();
    }
    
    private static final int HWND_BROADCAST   = 0xffff;
    private static final int WM_SETTINGCHANGE = 0x001a;
    private static final int SMTO_ABORTIFHUNG = 0x0002;
    
    public static void main(String[] args) {
         User32   user32   = (User32)   Native.loadLibrary("user32",   User32.class);
         Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
         
         HWND      handle = new HWND(new LongByReference(HWND_BROADCAST).getPointer().getPointer(0));  
         DWORD_PTR p      = new DWORD_PTR(0L);
         LRESULT   r      = user32.SendMessageTimeoutW(handle, WM_SETTINGCHANGE, 0, "Environment", SMTO_ABORTIFHUNG, 5000, p);
     
         System.out.println("DW ptr   = " + p.intValue());
         System.out.println("Last err = " + kernel32.GetLastError());
         System.out.println("lresult  = " + r.intValue());
    }
}
 

xjCoder

Aktives Mitglied
Hi KrokoDiehl,

Danke für Deine Mühe (und schön das Dich das Problem nun auch 'gefuchst' hat :toll: ).

Ich bin erst jetzt dazu gekommen Dein Beispiel auszuprobieren, bekomme aber immer einen Fehler:

Code:
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7e37cd36, pid=4556, tid=3980
#
# JRE version: 6.0_26-b03
# Java VM: Java HotSpot(TM) Client VM (20.1-b02 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [USER32.dll+0x1cd36]
#

...

...liegt aber bestimmt irgendwie an meiner Umgebung - werde ich mich wohl später mal mit befassen.


Inzwischen habe ich aber auch eine (für mich funktionierende) Lösung für mein akutes Problem gefunden.

Ich habe die problematische Pointer-Zeile
Code:
hwnd.setPointer(new IntByReference(User32.HWND_BROADCAST).getPointer (0));
durch
Code:
hwnd.setPointer(new Pointer(user32.HWND_BROADCAST));
ersetzt und siehe da - plötzlich klappt es wie gewünscht...


...habe mein kleines Beispiel mal entsprechend angepasst, falls es nochmal interessiert ;)

Java:
import java.util.ArrayList;
import java.util.Iterator;

import com.sun.jna.*;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.examples.win32.W32API.HWND;

import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RegistryValue;
import ca.beq.util.win32.registry.RootKey;
import ca.beq.util.win32.registry.ValueType;



public class EnvironmentRegistryTest
{
  public static void main(String[] args)
  {
    String envVar = "Path";
    
    String addToEnvVar = "test01";
    
    String envNow = new W32RegistryUsage().getEnvironmentRegistryKeys(envVar);
    System.out.println(envNow);
    
    new W32RegistryUsage().writeEnvironmentRegistryKey(envVar, addToEnvVar + ";" + envNow);
    
    User32 user32 = User32.INSTANCE;
    
    HWND hwnd = new HWND();
    hwnd.setPointer(new Pointer(user32.HWND_BROADCAST));
    
    user32.SendMessageTimeout(hwnd, user32.WM_SETTINGCHANGE, 0, "Environment", user32.SMTO_BLOCK, 1000, 0);
    
    System.out.println(new W32RegistryUsage().getEnvironmentRegistryKeys("Path") );
    
  }
  
  
  static class W32RegistryUsage
  {
    private String dll = "c:\\TEMP\\jRegistryKey.dll";
    private String regenv = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
    
    
    boolean writeEnvironmentRegistryKey(String regkey, String regvalue)
    {
      RegistryKey.initialize(dll);
      
      RegistryKey key;
      RegistryValue keyVal;
      
      ArrayList<String> list = new ArrayList<String>();
      
      key = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE, regenv);
      
      if(key.exists())
      {
        if(key.hasValues())
        {
          Iterator i = key.values();
          
          while(i.hasNext()) 
          {
            keyVal = (RegistryValue)i.next();
            
            if( keyVal.getName().toString().trim().equals(regkey) )
            {
              keyVal.setData(regvalue);
              key.setValue(keyVal);
              return true;
            }
          }
          
          //wenn ich hier bin scheint der Schluessel nicht zu existieren
          RegistryValue val = new RegistryValue(regkey, ValueType.REG_EXPAND_SZ, regvalue);
          key.setValue(val);
          return true;
        }
      }
      
      return false;
    }
    
    
    String getEnvironmentRegistryKeys(String regkey)
    {
      RegistryKey.initialize(dll);
      
      RegistryKey key;
      RegistryValue keyVal;
      
      String regvalue = null;
      
      key = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE, regenv);
      if(key.exists())
      {
        if(key.hasValues())
        {
          Iterator i = key.values();
          
          while(i.hasNext()) 
          {
            keyVal = (RegistryValue)i.next();
            
            if(keyVal.getName().toUpperCase().trim().equals(regkey.toUpperCase()))
            {
              regvalue = keyVal.getStringValue();
            }
          }
        }
      }
      
      return regvalue;
    }
    
  }  
  
  
  public interface User32 extends W32API 
  {
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, DEFAULT_OPTIONS);
    
    int HWND_BROADCAST = 0xffff; 
    int WM_SETTINGCHANGE = 0x1A;
    //int WM_SETTINGCHANGE = 0x001A; 
    int SMTO_ABORTIFHUNG = 0x0002;
    int SMTO_BLOCK = 0x0001;
    
    int SendMessageTimeout(HWND hwnd, int msg, int wParam, String lParam, int fuFlags, int uTimeout, int out); 
  }


}

...das JNA-Geraffel basiert aber auf einer alten Version (3.2.1) - ich habe es bisher noch nicht auf die Reihe bekommen
das Ganze anzupassen, werde mich wohl doch mal etwas mehr mit diesem Thema auseinandersetzen müssen :rtfm:


Besonderen Dank nochmal an KrokoDiehl für die Unterstützung! :applaus:

Ich mach den Thread jetzt mal zu...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R -jar der Windows-Registry hinzufügen Allgemeine Java-Themen 1
C jar File mehrfach aufrufen (als Windows Dienst) Allgemeine Java-Themen 5
izoards JAR als Windows Service mit Appache Procrun (prunsrv) Allgemeine Java-Themen 6
N JAVA-Code mit Grafikfenster zeichnet in Windows, aber nicht Mac. Allgemeine Java-Themen 4
HerrBolte Seltsamer Fehler nur in der Windows- und nicht in der Java-Console O_O Allgemeine Java-Themen 16
N iText keine Sonderzeichen und Umlaute unter Windows Allgemeine Java-Themen 13
MarekLanger Filebeat in Docker unter Windows Allgemeine Java-Themen 1
M Registry Autostart Eintrag mit Java erstellen (über Windows cmd) Allgemeine Java-Themen 7
S Java-Task-Management-Tool für Windows und Mac selber programmieren Allgemeine Java-Themen 4
M Console geht nicht auf (Windows 10) Allgemeine Java-Themen 3
M TomEE auf Windows Server 2016 installieren Allgemeine Java-Themen 4
Thallius Rätsel für Windows Profis Allgemeine Java-Themen 8
F Java Code ausführen direkt nach Anmelden in Windows Allgemeine Java-Themen 2
J jar Dateien unter Windows 7 mit spezifischer jdk öffnen Allgemeine Java-Themen 2
T Java Windows sounds erkennen Allgemeine Java-Themen 1
P Java als Windows Dienst Allgemeine Java-Themen 2
I GUI für kleine Pop-Ups unter Windows Allgemeine Java-Themen 1
H Änderung im maximalen heap space unter Windows 7 ?! Allgemeine Java-Themen 5
dereki2000 Windows Benachrichtigung erzeugen Allgemeine Java-Themen 2
Neumi5694 Task-Name unter Windows Allgemeine Java-Themen 4
M Checkliste mit erweiterbaren Einträgen, Baumstruktur, wie Windows Explorer Navigation Allgemeine Java-Themen 2
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
R JDK installieren JDK / Maven auf Windows 10 installieren Allgemeine Java-Themen 9
K jar-Datei lässt sich unter Windows nicht verwenden Allgemeine Java-Themen 3
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
D Jsch nur für Windows? Allgemeine Java-Themen 2
X JDK installieren Weiß jemand, wie ich GCJ (WINDOWS) installieren und anwenden kann? Allgemeine Java-Themen 11
D JRE in .jar verpacken unter Windows Allgemeine Java-Themen 4
I Programm im Hintergrund bei Windows zur Steuerung der Tastatur nutzen Allgemeine Java-Themen 2
D Aktuell installierte Java Version auslesen unter Windows Allgemeine Java-Themen 5
S Executable Jar File startet nicht unter Windows 10 Allgemeine Java-Themen 3
C Windows RCP Application unter Linux bauen lassen Allgemeine Java-Themen 3
E Anwendung verhält sich unter Mac anders als Unter Windows. Allgemeine Java-Themen 4
S JNLP startet seit 1.8.0_31 sehr langsam + Windows-Systemverzeichnis Allgemeine Java-Themen 3
M Windows 98 - Mit welchem JDK (Version) kann noch Programm dafür erstellt werden Allgemeine Java-Themen 6
Tom299 Beliebiges Windows-Programm / Prozess in den Vordergrund bringen Allgemeine Java-Themen 4
D Konsoleneingabe ist in Windows CMD nicht sichtbar Allgemeine Java-Themen 4
P Effizientes Programmieren - oder Windows Autostart fürs Herunterfahren Allgemeine Java-Themen 11
O Zugriff auf Windows Zertifikatstore Allgemeine Java-Themen 2
F Windows Umlaute Allgemeine Java-Themen 15
T Windows-Kontextmenü Eintrag hinzufügen? Allgemeine Java-Themen 3
O Socket-Unterschiede zwischen Windows und Ubuntu Allgemeine Java-Themen 2
G Wie installiere ich javax-usb unter windows? Allgemeine Java-Themen 0
M Swing Windows und Ubuntu Allgemeine Java-Themen 4
H JFileChooser soll NUR Windows-Netzwerkumgebung anzeigen Allgemeine Java-Themen 2
L Windows CMD werte Parsen. Allgemeine Java-Themen 2
M Code läuft unter windows aber nicht unter Linux Allgemeine Java-Themen 6
HarleyDavidson Tomcat VS Windows Scheduled Task Allgemeine Java-Themen 4
T JNI: kein Zugriff auf VM in Callback-Methode eines Windows-Hooks Allgemeine Java-Themen 3
W Windows (Service) Hooking Allgemeine Java-Themen 8
M Java auf Linux und Windows Allgemeine Java-Themen 6
R Windows-Firewall lässt Java nicht durch Allgemeine Java-Themen 17
R Java-Progamm über Icon starten unter Windows Allgemeine Java-Themen 9
N Input/Output Mit Windows 7 erzeugtes zip-File in Java 7 öffnen Allgemeine Java-Themen 5
P Eclipse Unter Windows erstelle .jar unter Linux (Ubuntu) funktioniert nicht Allgemeine Java-Themen 5
R ZIP FileSystem unter Windows wirft exception Allgemeine Java-Themen 7
njans Windows Verknüpfung von Icon Allgemeine Java-Themen 2
P windows mit java bedienen Allgemeine Java-Themen 8
P .Jar Datein Windows Konsole zugewiesen Allgemeine Java-Themen 3
C Encoding Problem Windows Allgemeine Java-Themen 9
L Input/Output ProcessBuilder und Windows - Konsole verbergen? Allgemeine Java-Themen 5
R Welches User-Verzeichnis wählen für Configurationsdateien - Windows Allgemeine Java-Themen 2
R Änderungen in einem Verzeichnis beobachten - Windows Allgemeine Java-Themen 3
A Nach Benutzerwechsel mit anderem Account in Windows anmelden Allgemeine Java-Themen 8
T Jar File läuft unter Windows aber nicht unter linux Allgemeine Java-Themen 10
B Windows Konsolenbefehle Allgemeine Java-Themen 3
Z Probleme bei Stringvergleichen (Windows/Linux) Allgemeine Java-Themen 10
B Windows Shutdown abfangen Allgemeine Java-Themen 10
E CMD Registry Key für Windows 7? Allgemeine Java-Themen 9
TiME-SPLiNTER vlcj und Windows Allgemeine Java-Themen 15
S Prozess der von anderem Prozess gestartet wurde beenden? (Windows Bildschirmtastatur) Allgemeine Java-Themen 4
G Input/Output URLDecoder.decode - Unterschiedliche Ergebnisse Windows / Linux Allgemeine Java-Themen 2
R Windows ermitteln ob Administratorrechte vorhanden Allgemeine Java-Themen 17
Y MenuBar -> Windows / Mac OS X Allgemeine Java-Themen 2
L Java Quellcode auf Windows 7 ausführen? Allgemeine Java-Themen 3
I Encoding Problem bei exec und Windows Allgemeine Java-Themen 2
R Windows - User Passwort ändern Allgemeine Java-Themen 2
F java prog als windows-dienst. Erfahrungen? Allgemeine Java-Themen 2
R Dateien vom Windows-Explorer zum Programm senden Allgemeine Java-Themen 21
H Standard Windows-Druck-Dialog Allgemeine Java-Themen 2
S Windows "öffnen mit..." Allgemeine Java-Themen 4
D Clipboard getSystemSelection() funktioniert unter Windows* nicht Allgemeine Java-Themen 3
M Nach Programmdurchlauf werden Zeichen falsch dargestellt + Anderes Verhalten unter Windows Allgemeine Java-Themen 6
P Windows Media Player starten / finden Allgemeine Java-Themen 2
D Windows-Konsole auslesen - Zeichenkodierung Allgemeine Java-Themen 4
J Path-Eintrag unter Windows 7 Allgemeine Java-Themen 11
Q .jar wird mit cmd gestartet - Zuordnung von Dateitypen ändern (Windows 7) Allgemeine Java-Themen 7
G jad JDK1.6 Windows 7 Allgemeine Java-Themen 2
Z Position/Größe von Windows-Fenstern ermitteln Allgemeine Java-Themen 12
Z Probleme mit Java unter Vista/ Windows 7 Allgemeine Java-Themen 12
O Jar-Datei auf Windows 98 Allgemeine Java-Themen 6
K Windows Fehlerkanal -> Ausgabe in Datei Allgemeine Java-Themen 6
M Runtime.getRuntime().exec(cmd); auf windows ... Allgemeine Java-Themen 2
P Runnable Jar File über Windows ausführbar doch über Linux nicht Allgemeine Java-Themen 8
A JavaVM Zeit Windows 7 Allgemeine Java-Themen 9
P USB Temperatursensor auslesen Windows Allgemeine Java-Themen 7
T Mac OS X <--> Windows XP Portierungsprobleme Allgemeine Java-Themen 7
G Textdatei einlesen unter Windows 7 Allgemeine Java-Themen 4
Benji0815 Verzeichnis wie im Windows Explorer in einem JTree anzeigen Allgemeine Java-Themen 6
P Die (Windows)MAC-Adresse vor 1.6 Allgemeine Java-Themen 9

Ähnliche Java Themen

Neue Themen


Oben