Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Composing a &macro with System Variables

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

How do I compose and run a command that contains windows variables like %PATH% and others as listed here: ?

Something like this...

Code:
lcDrive = 'E:'
Store "%PATH%\sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd
oWsh = Createobject("wscript.shell")
oWsh.Run(eCmd, 0, .F.)
Release oWsh

Thanks,
Stanley
 
Why?
If the command you want to RUN is in Windows path it will be ran w/o the need to point exactly in what folder it is.

Borislav Borissov
VFP9 SP2, SQL Server
 
>> Why?

Because I do not know how the target machine is configured and WHERE or IF the system has a system32, system, or syswow64 folders where lots of non-vfp applications live, like sdelete.exe. I've seen systems that has no c:, instead the boot drive is d:. So, I need a way to query the system for this and was hoping something native to vfp would do it. I know I can find the windows fully qualified paths with the GETOBJECT("WinMgmts... library, but was thinking vfp had native functionality.

The %Path% in the code I posted above is NOT the vfp path, instead I'm looking for using the "Windows Environment variables" which is very different from vfp's environment variables.

On my machine, the sdelete.exe file is located in the c:\windows\system32 folder, yet if I strip out the path part of the sdelete.exe command in the "store to" string above, I get something like "file not found" message. After several attempts to compose that line, I failed on all attempts, therefore I ask here...

Code:
Store "sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd

this line fails with file not found...

and the value of eCmd for this line (from above)...
Store "%PATH%\sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd

is... "%PATH%\sdelete.exe -p2 -s -q -z E:"

The macro is not substituting...

Stanley

 
The %Path% in the code I posted above is NOT the vfp path, instead I'm looking for using the "Windows Environment variables" which is very different from vfp's environment variables.

That's correct, which is why I suggested you use GETENV(). This returns all the Windows environment variables, such as PATH, WINDIR, TEMP, COMSPEC, etc.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
You can't use %PATH% nor GETENV("PATH") as it's not a single path but a list of paths the shell will look for files.

You can RUN /N notepad.exe without path as the system will find it along paths in %PATH%. So from that perspective you could add the path of sdelete.exe to %PATH%

But you install sdelete.exe together with your exe, don't you? If you don't, why not? Then it's simply located at the same place as your exe, which you find by SYS(16,0)

By the way: If you RUN /N C:\Windows\System32\notepad.exe you will run the notepad.exe in Syswow64 automatically, as 32bit processes access to the system32 folder is redirected to SysWow64. Also you could check the existence of SysWow64 via DIRECTORY(), GETENV("WINDIR") will give the windows base path, so check out, whether DIRECTORY(AddBS(GETENV("WINDIR"))+"SysWoW64")) is true.

Bye, Olaf.

 
Olaf, you're right about %PATH%, but I was just suggesting GETENV() as a general solution. You can use it, for example, with WINDIR or APPDATA to get specific paths - although it's not clear if that's what Stanley wants.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

>> That's correct, which is why I suggested you use GETENV(). This returns all the
>> Windows environment variables, such as PATH, WINDIR, TEMP, COMSPEC, etc.

Well, not so for me... When running _cliptext=GETENV("Path"), I get...
C:\Program Files (x86)\Embarcadero\Studio\17.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\17.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl\Win64;C:\ProgramData\Oracle\Java\javapath;C

Nowhere do I see C:\windows\system, or C:\windows\system32, or C:\windows\sysWOW64, or C:\program files, or C:\Program Files(x86).

My interpretation of my environment path as show from the getenv() commands above, my search paths are:
C:\Program Files (x86)\Embarcadero\Studio\17.0\bin
C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl
C:\Program Files (x86)\Embarcadero\Studio\17.0\bin64
C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl\Win64
C:\ProgramData\Oracle\Java\javapath
C

Therefore issuing sdelete.exe (which is in the c:\windpws\system32 folder) fails and should based on what the path is showing. It is not searching for anything in the windows folders.

I can just as easily put the sdelete.exe command somewhere in my vfp path, but that is not the nature of this question. Sdelete.exe is a command that is not installed in every windows install, and because of that I can put it anywhere in vfp's path. Now, what about all those other commands that is installed in every Windows install that I may choose to run within VFP via the run /n or equivalent command? This is the basis for this question. I think my example shows that.

Thanks Mike,
Stanley



 
Hi Olaf,

>> You can't use %PATH% nor GETENV("PATH") as it's not a single path but a list of paths the shell will look for files.

Yes, I see that now, and that explains why originally posted way failed... So i guess the question is now, How do I address a file that is in one of those windows folders via the vfp?


>> You can RUN /N notepad.exe without path as the system will find it along paths in %PATH%.

Yes that is true also, however sdelete.exe (which is in the c:\windows\system.32 folder) fails with a not found error from within vfp. It IS found when run from the windows command shell (outside of vfp). That is what started this question.


>> By the way: If you RUN /N C:\Windows\System32\notepad.exe you will run the notepad.exe in Syswow64 automatically, as 32bit processes access to the system32 folder is redirected to SysWow64. Also you could check the existence of SysWow64 via DIRECTORY(), GETENV("WINDIR") will give the windows base path, so check out, whether DIRECTORY(AddBS(GETENV("WINDIR"))+"SysWoW64")) is true.

So from this, what would the line look like

So, if DIRECTORY(AddBS(GETENV("WINDIR"))+"SysWoW64")) is true, then
Store "AddBS(GETENV("WINDIR"))+"SysWoW64")sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd
would work for 64bit machines?,

and if false,
Store "AddBS(GETENV("WINDIR"))sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd
is correct for 32bit machines?

I'll try it later today...

Thanks,
Stanley




 
I think the %SystemRoot% variable should always be present giving you the location of your Windows directory. Could you use a GETENV("SystemRoot") or GETENV("SystemRoot")+"\System32" to get what you need?

Edit: Didn't see your last post before sending this. Looks like %SystemRoot% and %WinDir% are almost totally interchangeable.
 
Hi bjitima,

Yes, I just tried your suggestion and it works if I test for each of the locations along the way. I'd have to test for the existance of GETENV("SystemRoot")+"\System32\sdelete.exe" and if not present, then another test for GETENV("SystemRoot")+"\System\sdelete.exe" until found.

What I was hoping for was a way to execute any executable in any of the possible windows locations using a single path for building a &macro or a evaluation routine. And expect it to work as long as the file is in those normal windows locations. As I said earlier, I have sdelete.exe in the c:\windows\system32 folder and it fails with a file not found error when run using vfp's run /n command.

What is also confusing is that I CAN use vfp's run /n command to run notepad.exe. That works fine, even though sdelete.exe does not. Why??

Thanks,
Stanley

Edit. Thanks for the article...
 
>So i guess the question is now, How do I address a file that is in one of those windows folders via the vfp?
I already said test if SYSWOW64 exists with DIRECTORY, if not you can use SYSTEM32.

Code:
Store "AddBS(GETENV("WINDIR"))+"SysWoW64")sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd
Rather [tt]Store AddBS(GETENV("WINDIR"))+"SysWoW64\sdelete.exe -p2 -s -q -z " + (lcDrive) To eCmd[/tt]

But why don't ou put sdelete.exe into your app directory, it doesn't need to go into the system folder at all. It's a download from Technet and not available on any system, so you have to install it anyway, why not in your application folder? Then you don't have to find out which system folder at all.

Please reread what I wrote, it's all there already.

Bye, Olaf.
 
Hi Olaf,

>> But why don't you put sdelete.exe into your app directory

Check out my message to Mike above with timestamp "Oct 15 18:19". I'll copy from message here, but there is a lot more in the message that discusses this in detail.

Stanley to Mike said:
Therefore issuing sdelete.exe (which is in the c:\windpws\system32 folder) fails and should based on what the path is showing. It is not searching for anything in the windows folders.

I can just as easily put the sdelete.exe command somewhere in my vfp path, but that is not the nature of this question. Sdelete.exe is a command that is not installed in every windows install, and because of that I can put it anywhere in vfp's path. Now, what about all those other commands that is installed in every Windows install that I may choose to run within VFP via the run /n or equivalent command? This is the basis for this question. I think my example shows that.

Thanks Mike,
Stanley

Thanks,
Stanley
 
Stanely,

You say you want "a way to execute any executable in any of the possible windows locations ... And expect it to work as long as the file is in those normal windows locations. "

If by "any of the possible windows locations" you mean the directories on the Windows path, then you already have that. Just execute the program without worrying about its path. That applies regardless of whether you use RUN, ShellExecute or wscript.shell.

If you mean you expect the program to be in certain standard locations such as the Windows directory or the Program Files directory, but not necessarily on the Windows path, then you will just have to try each of those locations in turn. So, first use GETENV() to get the location of %WINDIR%, then try to execute the program there; if that returns a "not found" error, try %PROGRAMFILES%, and so on. It's tedious, but I don't see how else you can execute a program without knowing where it is.

(And, by the way, you say that the Windows and System directories don't show up in your GETENV("PATH"). I suggest you find out why. I don't recall ever seeing a Windows system where those directories aren't in the path.)

Final point. If your application needs to securely delete files, but you can't be sure that SDELETE.EXE is present, why not distribute it with your application. My understanding is that it is a freely distributable utility (you will want to check that). You could therefore place it any known location, including your application's home directory, where you are sure to find it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike is right in saying "Just execute the program without worrying about its path"

You can RUN /N notepad.exe and windows finds it, as it searches along %PATH% paths and more (system32 isn't in ma %PATH%). The only thing not nice abut this is, if something is in two folders and you might get the wrong version started. This also doesn't work with any EXE, I'd dare to say without looking for an example even not for any system EXE.

Another mechanism helps you: If you run as a 32bit application system32 access automatically is redirected to syswow64, so actually you can but don't need to check which path exists. Much more general: Programs installed have their location registered in the registry.

My habit about this is rather install it once more, if it's not deeply embedded and only works at a system location, or finding an alternative API call I can DECLARE (you just need the dll name here for windows dlls), or finding an ole class I can instanciate without knowing paths. I never had the need to know whether something is in system32 or syswow64 or wherever else.

Bye, Olaf.
 
Hi Guys,

I've said it more than once here, sdelete and notepad are both in the c:\windows\system32 folder.
Look at the 2 screenshots showing each

Running run /n sdelete.exe DOES NOT WORK...

Running run /n notepad.exe WORKS...

Also like Olaf, c:\windows\system32 is not in my PATH either,

Running ?GETENV("Path"), I get...
C:\Program Files (x86)\Embarcadero\Studio\17.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\17.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl\Win64;C:\ProgramData\Oracle\Java\javapath;C

Yes Olaf, I am aware of the different version collision possibilities when running 32bit apps on a 64bit machine, but that is not the issue here. I learned that when doing the odbc stuff some time ago.


>> You say you want "a way to execute any executable in any of the possible windows locations

Yes Mike, that is exactly what I was trying to do with mixed results. I actually assumed (wrongly) that files placed in the windows locations would be available and that clearly doesn't work as I have demonstrated.

For a long time now, I have had sdelete.exe in the system32 folder and have used it many times from the dos prompt via the OS. It always ran without error. Then early this week, I added it to the excryption script I'm working on and it would NOT work. So, why was the question? That also got me thinking about ANY other executable that may be in the windows locations. That caused me to stop thinking about just the sdelete issue and focus on a much larger issue of why some exes will run and others will not, and that is where the "ANY" came from.

I've noticed that everyone has been focused on getting sdelete to work by controlling its location and that is acceptable, however, they are missing the bigger issue here. And that is, why won't it work like notepad when it lives in the same place as notepad. And is this sort of unexpected behavior expected?

Thanks,
Stanley
 
Just foulnd out something interesting...

When going to the system's environmental settings and locating the PATH variable it's value is:
C:\Program Files (x86)\Embarcadero\Studio\17.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\17.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl\Win64;C:\ProgramData\Oracle\Java\javapath;%C_EM64T_REDIST11%bin\Intel64;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Smart Projects\IsoBuster;C:\Program Files\EmEditor;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files (x86)\Common Files\Acronis\SnapAPI\;C:\LEADCMD;C:\LEADCMD\Bin;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;C:\GdPicture.NET 10\Redist;C:\Progr

Now when running ?GETENV("Path"), I get...
?GETENV("Path")]C:\Program Files (x86)\Embarcadero\Studio\17.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\17.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl\Win64;C:\ProgramData\Oracle\Java\javapath;C

which is exactly 256 characters long which means truncating is happening. With this going on, how can we ever trust GETENV("Path")??

Thanks,
Stanley
 
Looks like you've discovered a bug in GETENV(). In fact, I'm seeing the same thing. My PATH string is also truncated at 255 characters.

So, you need to use the Windows API function instead. It's called GetEnvironmentVariable(), and it takes as parameters: (i) the name of an environment variable ("PATH" in this case); (ii) a buffer to store the result in (this is just the name of a variable holding a long string of spaces); and (iii) the length of the buffer. The function returns the contents of the environment variable in to the buffer.

You can see an example of this on the Bereznikers' site. See Ignore most of the code on the page. Just focus on the function named GetEnvVar().

And you can find more information here:
Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Great, that I'm not going crazy... (at least not yet)

I'm glad you're calling it a bug, as that is what I believe it is...

Now, back to the question of why notepad works and sdelete does not, even when they both exist in the same system32 folder. The bug as you pointed out has no bearing on this, does it?? If so, please piont it out...

Thanks,
Stanley
 
notepad.exe is in both system32 and syswow64, there are both 64bit and 32 bit versions of it.

If you put sdelete.exe in system32 you have still not understood that any 32bit process call into system32 is redirectred into syswow64, where it's not found.
If you put sdelete.exe somewhere, put it in your app folder, not into system32, it's not reachable to you in there.

Also: system32 folder is the 64bit tools folder, syswow64 is short for system window32 on windows64 and is the 32 bit tool folder. At this point I always add: Don't blame me for Microsofts ill naming logic.

When you RUN notepad.exe or RUN /N notepad.exe, then look into task manager you'll find notepad.exe *32 in the task manager, the 32bit version was started from VFP. If you run notepad.exe from system32 you find notepad.exe without *32, that's the 64 bit notepad.

Now, that doesn't mean you can't run 64bit processes, if you copy the 64bit notepad.exe of the system32 folder somewhere else, eg c:\test\ and run c:\test\notepad.exe, then you find the 64bit process in the task manager.

Bye, Olaf.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top