Archive: HowTo: invoke Kernel32 to SetEnvVar with system::Call?


HowTo: invoke Kernel32 to SetEnvVar with system::Call?
<alert comment="nsis newbie">

I'm fuzzy on how to actually invoke the system.dll plug-in to set an environment variable. The following archive link shows two ways to accomplish this and I'm attempting to use the first approach described ... but it isn't working for me:
http://nsis.sourceforge.net/archive/...php?pageid=161

Here is TestSetEnv.nsi, which I would think would cause the environment variable "DID_IT_WORK" to "YES"


Name "TestSetEnv"
OutFile "TestSetEnv_setup.exe"
InstallDir $PROGRAMFILES\TestSetEnv
InstallDirRegKey HKLM SOFTWARE\TestSetEnv "Install_Dir"

Section "TestSetEnv (req with s/w)"
SectionIn RO
SetOutPath $INSTDIR

StrCpy $R0 "YES"
system::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("DID_IT_WORK", $R0).r0'

SectionEnd


When I try something very similar, nothing seems to happen. Is there something else I need to do in my script to let the system.dll plug-in be used?

How do I have the environment variable DID_IT_WORK be created with the value "YES"?

I looked at the top of the compiler output, and system::call was shown.

</alert>

SetEnvironmentVariable sets the environment variable just for the current process. If you want to set it for the entire system, use WriteEnvStr.


Ahh ... now it is becoming much clearer <g>

Thanks. Seems to work fine. I can now look in "System" + "Environment Variable" and see that DID_IT_WORK is set to "YES". Also, I can start a "DosPrompt" window and have
C:> set di
confirm that DID_IT_WORK is "YES". Cool.

A related (followup) question ... I tried to have the TestSetEnv.nsi have a confirming MessageBox that it worked. In the snippet from that script below, I was expecting:

* R0 would have the TEMP value (worked)

* R1 would be blank (yes)

* R2 would have "YES" (was still blank)

Is there some kind of delay or sync?

ReadEnvStr $R0 TEMP
ReadEnvStr $R1 DID_IT_WORK

Push "DID_IT_WORK"
Push "YES"

Call WriteEnvStr

ReadEnvStr $R2 DID_IT_WORK
MessageBox MB_OK "RO (TEMP) is set to $R0 \
$\r$\nR1 (before) is set to $R1 \
$\r$\nR2 (after) is set to $R2"


WriteEnvStr only updates running processes that are capable of updating the environment on runtime. The only process I know that does this is explorer.exe. NSIS doesn't do it and that's what you're seeing. For it to update immediately, you need to use the previous method you've used.


Ok. I can certainly live with that. It isn't important to the nsis installer that the environment variable got set ... the application is what cares.

And THANKS VERY MUCH for the very timely, patient, and helpful replies.

Just wondering, if the WriteEnvStr routine had a problem, would it be detected by IfErrors in the calling script? I didn't see any error handling in the WriteEnvStr.nsh code, but I'm not all that experienced at looking at nsis script.

What would be the "best practices code" to make sure the environment variable was set (such as if an NT/Xp user didn't have admin privilege)?

Would the following snippet be appropriate:

Push "DID_IT_WORK"
Push "YES"
ClearErrors
Call WriteEnvStr
IfErrors WriteEnvStrProblem WriteEvnStrOk

Or does WriteEnvStr.nsh fail "silently"?