Archive: PLUGINSDIR and 2003 Server


PLUGINSDIR and 2003 Server
Hello. I love this installer. Writing the script has been fun, and so far, I have been able to make it do whatever my very demanding users can think of.

One place I got stuck: I have incorporated the Python language plugin ( oh, the power! ) to help perform some of the installer's trickier tasks. It works on Win2000 and XP but the production target is Windows 2003 Server. There, I cannot load the nspython.dll. I tested with the simple installer that comes with the plugin and this is what I found:

- cannot load dll when InitPluginsDir command is invoked
- cannot load dll when PLUGINSDIR name is changed using the "change variable plugin"
- I CAN get it to work if I do not use the InitPluginsDir command *and* the dll resides in the same directory as the installer exe.

So I have a work-around. But making the user find the exe in a directory with the dll and all the .pyc files is kinda ugly.

What am I missing here? Thanks.


Are you installing on a 2003 server with Terminal Services enabled?


Yes. These severs are TS enabled


ARGH! I was afraid you'd say that! Terminal Services is a whole different animal. And looking through the forums, there hasn't been too much written about as far as NSIS is concerned.

First, based on Microsoft's recommendations, you should always make sure you run any Terminal Server installation via the add/remove programs control panel. (This ensures the proper folder redirection to occur during the installation.)

If you are still having problems, you might need to make sure that you have full access to the TEMP folder (and make sure you know where temp really is). This is becuase Windows can redirect the TEMP variable in Temrinal Services. An easy way to find TEMP is to run "%TEMP%" from a run box. It should take you right into wherever TEMP is define for the user. Then, make sure you are able to create and delete files/folder in this directory. (TEMP is where the PLUGINS directory is actually created.)

Please let me know what you find. I'm very curious!


Thanks for the ideas. Unfortunately things still did not work out.

I do have authority on the temp folder. I am an administrator on these deployment boxes.

I also tried installing from Add/Remove programs - to no avail.

Just to make sure I was not insane, while the temp folder still existed (before I closed the installer), I droped the exe into the tempdir where all the dll's resided. This one did work. So far, then, the only way I've found to make this work is to co-locate my plugin stuff with my installer (yuck).


You could manually extract the plugins you use to a localised folder (like "$EXEDIR\setuptmp") then call them with CallInstDLL

To pass the paramaters you have to Push them first, in reverse order (so last params are Push'ed first).

-Stu


That would work great if we were talking about some other plugin besides python. To use any of python's library in your install functions (and I do), you must also deploy the modules that support those library functions. These are all .pyc and .pyd files and they must be found by the python interpreter in your path. Thanks.


hmmm...
I wonder if Terminal Services is the problem or something else. Have you tried on a Win2k3 without T/S?

Also I looked at the python plugin here: http://nsis.sourceforge.net/archive/...instances=0,32

I wonder what would happen if the code were modified slightly to use a SetOutPath statement to go from this:


Function .onInit
;Extract Install Options files
InitPluginsDir
File "/oname=$PLUGINSDIR\python23.dll" "python23.dll"
File "/oname=$PLUGINSDIR\test.py" "test.py"
FunctionEnd


to this:
 
Function .onInit
;Extract Install Options files
InitPluginsDir
SetOutPath "$PLUGINSDIR"
File "python23.dll"
File "test.py"
FunctionEnd

Testing on my Win2k box and the results seemed the same. I just wonder if this small change would make it work better for you on the Win2k3 server.

(I work some with Win2k3 Terminal servers at my 'real' job, but unfortunatley, I don't have one setup for my own personal use. Otherwise, it would be no problem for me to test these things myself...)

Bless you, my friend. That works! But... why?


That is a very good question...

Perhaps one of the developers might have an answer.


SetOutPath also sets the current working directory. Besides this, using SetOutPath is no different than using File /oname.


I wanted to post a followup because there is very little on this list that addresses the issues I've grappled with. This is a fine tool and a great community and I want to prevent someone else from diving down the same ratholes.

Comperio was right: Terminal Services is a whole different animal (its a rat).

If you are logged onto the target of your installation through TS, there is no way to change many elements of the system execution environment during the execution of your installer.

My installer uses the python nsis plugin. It is just beyond belief to have the power of python to help perform install tasks. But, it posed some problems in the installer's execution environment. I got the python23.dll to load by following Comperio's suggestion found in this thread. But, the other files needed (such as .pyd and .pyc files needed by my python scripts) still could not be found by the installer.

Basically, .pyd files are dll's that python23.dll itself wants to load. The .pyc files are byte code files that the python interpreter must find. In the execution environment, your dll's must be found somewhere in your PATH and python modules can normally be found in PATH or in a directory pointed to by a PYTHONPATH environment variable. Within Terminal Services, none of these files can be found in the PLUGINSDIR. This is everything I tried, to no avail, to get my .pyd and .pyc files found:

- I changed the value of PLUGINSDIR using the "change variable" plugin
- I added the PLUGINSDIR to the PATH variable for the life of execution
- I created a new directory which I added to the PATH variable for life of execution
- I created a new directory which I added to the PATH variable permanently

The last one did not work during the execution of the installer, but a subsequent execution found the .pyd files in that direcory. The .pyc file were found, sort of. The python scripts only produced a copy of the script instead of executing the script. In terms of python, it looked like we needed one more level of 'eval.'

This is what worked: Permanently adding a new directory to the PATH environment variable and *also* adding that directory to the PYTHONPATH environment variable. This had to be done before the execution of the installer. When the installer dumped everything into this directory, it all worked. However, this directory could not be removed during execution of the installer because python23.dll and all .pyd files where still loaded and "in use."

To summarize:
You cannot change the PLUGINSDIR, modify the PATH or any other environment variable temporarily or permanently during the execution of the installer while logged on through Terminal services.

If you are logged onto Terminal Services: In order to use python in your installer where your script needs python library modules, you must place all .pyd files in a directory pointed to by PATH and all .pyc files in a directory pointed to by PYTHONPATH. These environment settings must exist *before* the execution of your installer.


Since environment variables are copied to child processes, it might work if you set them for the installer process instead of the whole system.


Yes. I tried this. That is what I meant by:

"I created a new directory which I added to the PATH variable for life of execution." It no work.

What is the "child" process in this instance? And whom is the parent?


The parent is the installer itself and the child is python.exe. You're using the plug-in, so there's no python.exe and my description doesn't fit so good. However, setting the PATH environment variable for the current process does affect the paths LoadLibrary, used to load plug-ins, uses. It also searches for dependencies of the plug-in, including python23.dll. Assuming Python uses normal methods to load DLLs, it should be also used to find the .pyd files. If not, setting PYTHONPATH in the installer process itself, using SetEnvironmentVariable should be no different than setting it for the entire system before running the installer.

Another path LoadLibrary uses to find dependent DLLs is the current working directory, which is set by SetOutPath. Python should also be using this for loading both pyc and pyd files. The import directive looks in the current directory, so should this.

Anyway, this is all nice and dandy for non-TS Windows. Obviously, if the script worked without changes on 2000 and XP and doesn't work on TS, something is different there. The first thought that comes to mind is that you had Python installed on the 2000 and XP machines so it found python23.dll in the system directory. But I'm sure you've already tested that.

I've probably missed something during this long thread (my the deep deprivation of sleep probably helped), so, if you don't mind, I'd like to get back to square one in order to find the best solution which doesn't require the user to change environment variables before starting the installer. Can you attach a script that works on 2000 and XP but doesn't work on 2003 TS?


While working up a simple example to post here, I discovered what works.

Firstly, setting the PATH variable for the process using the SetEnv plugin, as kichik suggested, always works. I couldn't get it to not work in my simple example. It still does not work in my 2000 line installer, but I'll figure that out.

Secondly, you can dump all your python stuff into the PLUGINSDIR *if* you SetOutPath $PLUGINSDIR just before you invoke the nsPython plugin.

Terminal Services isn't such a rat after all.

May you sleep deeply, kichik. May your dreams be sweet. May you rise with a smile.

Thanks