Is it possible from an app to set the environment for the spawned cmd.exe so that customer paths and variables are known?
a) Make the shell mode 2 and send commands to set up the environment when you first create it.
b) Write out a shell script and have cmd.exe execute that. Put your setup in the script.
I was pretty sure, but hope springs eternal. I also learned the hard way that Shell.Backend = “myzsh.exe” doesn’t do good things, either (feature request in on that, though…). Time for more refactoring to make an old OS X / Linux tool Windows-fide.
I am learning to despise Windows more and more each day. So much so that I’m thinking about licensing CygWin as part of our app to make the trifecta more of a “win” situation than a “when” situation so that the Unix goodness that I’m used to is easily duplicated.
On Windows you CAN run cmd.exe and that should set up the windows environment
For history and the forum archive - The problem there is that you lose the Completion event and also can’t depend on “IsRunning” by default. To fix this, you must remember to add an “exit” command to the end of your command sequence. Here’s an example that calls “ls” (part of my specialized Unix-y environment) and displays the result in a TextArea:
Dim theShell As New Shell
Dim thePathEnv As String
theShell.Mode = 2
theShell.TimeOut = -1
theShell.Execute "cmd.exe /q"
theShell.WriteLine "prompt $b"
theShell.WriteLine "echo START"
theshell.WriteLine "ls -l C:\"
theShell.WriteLine "echo FINISH"
theShell.WriteLine "exit"
Do
App.DoEvents // don't judge
Loop Until Not theShell.IsRunning
TextArea1.SelText = NthField(NthField(theShell.ReadAll, "START", 2), "FINISH", 1)
The results will look something like this:
|total 813188
drwxrwxrwx 1 user group 0 Mar 15 18:06 $Recycle.Bin
-rw-rw-rw- 1 user group 1 Jun 18 2013 BOOTNXT
drwxrwxrwx 1 user group 0 Aug 22 2013 Documents and Settings
dr-xr-xr-x 1 user group 0 Mar 15 18:09 MSOCache
drwxrwxrwx 1 user group 0 Mar 15 17:27 NVIDIA
drwxrwxrwx 1 user group 0 Aug 22 2013 PerfLogs
dr-xr-xr-x 1 user group 0 Mar 31 01:31 Program Files
dr-xr-xr-x 1 user group 0 Apr 2 16:42 Program Files (x86)
drwxrwxrwx 1 user group 0 Apr 2 18:08 ProgramData
drwxrwxrwx 1 user group 0 Apr 2 07:02 System Volume Information
dr-xr-xr-x 1 user group 0 Mar 15 18:04 Users
drwxrwxrwx 1 user group 0 Apr 1 14:52 Windows
-r--r--r-- 1 user group 427680 Aug 21 2013 bootmgr
-rw-rw-rw- 1 user group 5078 Mar 15 18:07 cpqsprt.trace
drwxrwxrwx 1 user group 0 Mar 15 18:07 cpqsystem
-rw-rw-rw- 1 user group 815493120 Apr 2 16:44 hiberfil.sys
-rw-rw-rw- 1 user group 0 Apr 2 16:44 pagefile.sys
-rw-rw-rw- 1 user group 16777216 Apr 2 16:44 swapfile.sys
|
Note that you could further strip the “|” symbols (from the “prompt $b” command). I also tried using “echo off” instead of setting the prompt, but sometimes I need to execute multiple commands and the “|” lets me separate the results.
Ah yes about the events that won’t fire as expected if you do run cmd.exe
And could you not just yield to next thread instead of do events ?
Hey - you judged :P. Actually, any type of yield works there. That was just from a helper console app that I use. I threw the TextArea into the code so others could see the effect of the prompt and nthfield operations.
No
Judging would be “OMG TIm really DO EVENTS ?”
If all you need is any kind of yield then the loop boundary functions as one so you could just sleep the current thread
:S
Except that the code was from a Console app where DoEvents is the best solution.
On windows there is another way to do this by use of OLEObject.
This example is using environment type: Process which is not stored in the registry.
Dim wshShell As OLEObject
Dim objEnv As OLEObject
Dim envString as String
Dim myShell As Shell
wshShell = New OLEObject("WScript.Shell")
objEnv = wshShell.Environment("Process") // Using Environment type: Process Not stored in the registry
envString = OBJenv.Item("PATH")
msgbox("Before: "+EndOfLine+EndOfLine+envString)
objEnv.Item("PATH") = envString+"C:\\bin\\ProcessExplorer" // Installed ProcessExplorer from Sysinternals
envString = OBJenv.Item("PATH")
msgbox("After: "+EndOfLine+EndOfLine+envString)
myShell = New Shell
myShell.execute("procexp.exe") // run ProcessExplorer
wshShell = nil
exception err as oleexception
msgbox err.message
If you want to store your environment in users profile. You use environment Type: User
You only need to change this line from: objEnv = wshShell.Environment(“Process”) to: objEnv = wshShell.Environment(“User”)
You can find more information about this on: http://technet.microsoft.com/en-us/library/ee156595.aspx
You CAN set environment variables via System.EnvironmentVariable and those values will be set in the Shell process. I had forgotten that when I wrote my response back in November.
Thanks Tim
I had forgotten that too.
LOL Xojo has too many features
Link is here: http://documentation.xojo.com/index.php/System.EnvironmentVariable