2011-10-20 3 views
1

Dans mon projet Openscript, j'ai besoin d'un redémarrage pour enregistrer les valeurs des variables d'environnement. Mais je veux que cette application devrait être installée sans redémarrage. Est-ce que c'est leur moyen d'actualiser les valeurs de la variable Environment pour que mon application soit enregistrée et qu'aucun redémarrage n'est nécessaire? J'utilise déjà suivant la ligne de code:Actualisation de la valeur des variables d'environnement

define WM_WININICHANGE 0x001A' 
define HWND_BROADCAST 0xffff' 
szEnv = "Environment"; 
pEnv = &szEnv; 
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, pEnv);` 

Leur est une autre façon d'actualiser les valeurs des variables d'environnement? Je cours cela sur Windows XP.

+1

Si vous utilisez ** InstallShield 2010 ou version ultérieure **, le code ci-dessus ne fonctionnera pas. Voir ici pour la solution: http://stackoverflow.com/questions/2103790/batch-file-cant-immediately-see-environment-variables-created-by-installshield/20362751#20362751 –

Répondre

0

Un processus Windows qui définit une variable d'environnement ne peut pas accéder à cette variable pour la lecture. C'est une limitation dans Windows. L'idée est que si votre processus définit une variable, il connaît déjà la valeur de la variable. Par conséquent, si votre programme d'installation définit une variable d'environnement, votre application doit s'exécuter dans un processus séparé et indépendant pour lire cette variable. C'est pourquoi le lancement de l'application à la fin de l'installation ne fonctionne pas.

Une solution consiste à transmettre la valeur de la variable via la ligne de commande de l'application lors du lancement lors de l'installation. Tous les lancements futurs auront toujours accès à la variable directement. L'envoi du message WININICHANGE à l'adresse de diffusion est la bonne chose à faire.

0

Cependant, il n'est pas nécessaire que tous les processus en cours sous-classifient correctement ce message et mettent à jour leurs variables d'environnement pour ce processus. Ils sont censés le faire, mais cela n'arrive pas toujours. L'exemple le plus notoire de ceci est le gestionnaire de contrôle de service. Vous devez redémarrer pour que le SCM puisse voir la nouvelle variable/valeur.

Maintenant, si vous demandez "comment puis-je obtenir mon processus en cours pour voir cette valeur?" (Cosmin semble penser que est ce que vous demandez, mais je ne suis pas sûr si vous êtes ou non), la réponse réside dans la compréhension que l'espace de l'environnement a quatre collections:

utilisateur machine processus volatils

http://msdn.microsoft.com/en-us/library/6s7w15a0(v=vs.85).aspx

Ce que votre code fait est de définir l'environnement var pour SYSTEM. C'est comme les vieux jours où vous mettriez une ligne dans votre autoexec.bat (SET FOO = BAR) et redémarrer. Mais vous pouvez aussi créer une nouvelle invite DOS à partir de Windows et faire SET SOMETHING = ELSE et cela ne sera visible que pour la vie de ce processus et des processus fils mais pas d'autres processus. C'est l'espace "Process" par rapport à l'espace "System". De plus, si vous mettez à jour AUTEXEC.BAT avec une nouvelle variable et créez un nouveau processus sans redémarrer, il ne verra pas la nouvelle variable mais vous pourrez toujours la définir et la voir (bien que techniquement pas la même).

Je sais, avec SendMessage vous ne devriez pas avoir besoin du redémarrage, mais tous les processus n'obtiendront pas le message. Par conséquent, si vous avez besoin du processus InstallScript actuel pour avoir cette nouvelle variable, vous devez appeler la fonction SetEnvironmentVariable de Kernel32 qui, selon MSDN, définit le contenu de la variable d'environnement spécifiée pour le processus en cours.

Intéressant InstallScript a une fonction GetEnvVar mais pas une fonction SetEnvVar, vous devrez donc le prototyper en tant que fonction externe, puis l'appeler.

Une discussion avec des échantillons peut être trouvée here.

Questions connexes