how to set the environemental variable permanently?

New to FreeBASIC? Post your questions here.
Post Reply
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

how to set the environemental variable permanently?

Post by oyster »

I want to burn a app on one cd, which can set the environemental variable according to the real cd driver letter when inserted. For exapmle, it sets path=g:\tool if the cd is assigned as g:, and path=h:\tool for h:
but it seems that setenviron does not change the environemental variable out of the .bas program

Code: Select all

' test.bas
? "before"
? environ("Path")

setenviron "PATH=c:\"

? "after"
? environ("Path")

shell "PATH=c:\"

? "after"
? environ("Path")
and this is my test

Code: Select all

D:\launch tool>path
[b]PATH=d:[/b]

D:\launch tool>test.exe
before
d:
after
c:\
after
c:\

D:\launch tool>path
[b]PATH=d:[/b]
you may find that path is not varied totally!
Any suggestion? plz note I can not write a .bat file to cd and then run the .bat file, and I don't like the .bat solution.

I am using offical fbc 0.16b on simplified chinese win2k with sp4. and I test the above code under the dos prompt

thanx
DrV
Site Admin
Posts: 2116
Joined: May 27, 2005 18:39
Location: Midwestern USA
Contact:

Post by DrV »

You can't modify the system-wide environment; each process gets its own copy of the environment on startup, which is copied to any child processes when they are spawned. You could execute a shell with a modified environment, if that is useful:

Code: Select all

setenviron("PATH=c:\")
shell environ("COMSPEC")
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

Post by oyster »

thank you, DrV
that is so bad
Zippy
Posts: 1295
Joined: Feb 10, 2006 18:05

Post by Zippy »

Well, ok. You can do this (make programmatic perm changes to the global environment). BUT it requires modding the registry - appears to be not too dif on a user basis, but would require Admin rights to effect for all users.

Would it work, can you write this tiny bit of data (path) to a file in the TEMPDIR where it can be retrieved later?
jonathanbrickman0000
Posts: 189
Joined: Dec 23, 2005 21:16
Location: Topeka, Kansas, USA
Contact:

Post by jonathanbrickman0000 »

That comes awful close to nearly-malware :) Definitely, if I installed any code off the Net that did that to my machine without very explicit permission, it would be deinstalled very quickly!
Zippy
Posts: 1295
Joined: Feb 10, 2006 18:05

SetEnv GetEnv

Post by Zippy »

jonathanbrickman0000 wrote:That comes awful close to nearly-malware :) Definitely, if I installed any code off the Net that did that to my machine without very explicit permission, it would be deinstalled very quickly!
;-) Look at your PATH lately? The last thing I installed off the 'net was GNU wget. It modded the global PATH (I of course installed as Admin..).

XP is (still) a Great Gaping Security Hole. A regular user can (still) cripple the OS, either deliberately or with the help of malware/viruses. I administered University Unix systems for years, opened them up to students for external access, never had a problem (OK, one version of Apache was hacked once) - and they tried to break them.

Sigh. I think that VISTA will allow me to RUNAS a regular user, with Admin access as needed (when accessed). But I'll have to be dragged to that upgrade kicking and screaming.

-----

Ok, here's Set/GetEnv (see Notes:):

Code: Select all

'set/getenv, Windows only - REQUIRES WinNT or newer!
' Don't use on/for Win9x
' tested using fb v0.16 release on XP only
'Mods the registry - use at your own risk!
option explicit
#include "windows.bi"
#include "win\winreg.bi"
#define HKCU (CAST(HKEY,&H80000001))
#define SAFE

declare function SetEnv(mykey as string,myval as string) as integer
declare function GetEnv(mykey as string) as string
dim as string mykey,myval,envres

mykey="Zippy" 'key in HKCU\Environment to set
myval="c:"   'value to set

SetEnv(mykey,myval)

envres=GetEnv(mykey)
print mykey;"=";envres

1 'mykey="PATH"
2 'myval="%PATH%" & ";z:"
3 'SetEnv(mykey,myval)
4 'envres=GetEnv(mykey)
5 'print mykey;"=";envres

sleep
end
'''''''''''''''''''''''''''''''''''
function SetEnv(mykey as string,myval as string) as integer
    dim as HKEY keyhandle
    dim as integer res

#ifdef SAFE
    if left(mykey,1)<>"Z" then
        beep
        print "Key must begin with 'Z',"
        print " sleeping to EXIT.."
        sleep
        end
    end if
#endif

    res=RegCreateKeyEx(HKCU,_
                       "Environment",_
                       0,_
                       0,_
                       REG_OPTION_NON_VOLATILE,_
                       KEY_SET_VALUE,_
                       NULL,_
                       @keyhandle,_
                       0)
                  
    res=RegSetValueEx(keyhandle,_
                      strptr(mykey),_
                      0,_
                      REG_SZ,_
                      strptr(myval),_
                      len(myval))
                      
    RegCloseKey(keyhandle)
    return 0
end function
'
function GetEnv(mykey as string) as string
    dim as HKEY keyhandle
    dim as integer res,dtype,lenvbuf
    dim as string envbuf
    
    if len(mykey)<1 then
        beep
        print "Invalid Key..,"
        print " sleeping to EXIT.."
        sleep
        end
    end if
    
    res=RegCreateKeyEx(HKCU,_
                       "Environment",_
                       0,_
                       0,_
                       REG_OPTION_NON_VOLATILE,_
                       KEY_QUERY_VALUE ,_
                       NULL,_
                       @keyhandle,_
                       0)
                       
    envbuf=space(2048)
    lenvbuf=len(envbuf)
    res=RegQueryValueEx(keyhandle,_
                        strptr(mykey),_
                        NULL,_
                        @dtype,_
                        strptr(envbuf),_
                        @lenvbuf)
                        
    RegCloseKey(keyhandle)                    
    return left(trim(envbuf),lenvbuf)
end function

Notes:

1. @yetifoot and @oldirty contributed to this code, albeit I doubt they know this.. This addresses only HKCU\Environment.
2. SetEnv() is crippled, deliberately. There's zero error checking beyond that the key must begin with a "Z", change at will but don't cry to me if you hose your system. Comment-out "#define SAFE" if you want to enable/write arbitrary environ vars.
3. There doesn't appear to be a reliable method to notify all programs of a/the changed environment, short of a reboot or relogin. Thus "GetEnv()" which does reflect all changes. fb environ() does not (but does/will after reboot/relogin) - this is NOT a bug in fb, rather it is expected behavior.
4. Both Set/GetEnv are string-based. REG_SZ.

5. The user's PATH can be modded without changing the global PATH, which may have been the original question/problem.. One should either append or prepend to the global path, not replace it outright. Lines #1-#5 demo an append to PATH (requires the "enable" in Note 2 above).

ETA: Requires WinNT or newer
Last edited by Zippy on Jul 16, 2006 17:48, edited 1 time in total.
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

Post by oyster »

thank you everyone, but what I want is a more portable or green( do not modify the sys at all) solution. Now maybe the conclusion is that that is impossible.
ytwinky
Posts: 217
Joined: Dec 03, 2005 12:44
Location: MD, Germany

Post by ytwinky »

Zippy wrote:Sigh. I think that VISTA will allow me to RUNAS a regular user, with Admin access as needed (when accessed).
You don't really need Vista to do this..
..just hal @ AutoIt3, it is possible to RunAs with adminrights whichever command you like(without the need of entering domain, username, password)
(You should always use the latest beta, for extended functionality..)
regards
ytwinky
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

The best way would be to use an install maker. That way the modifications to the system can be clearly stated to the user at the time of install and the installer can worry about OS specifics (9x sets environment variable different then NT).
Zippy
Posts: 1295
Joined: Feb 10, 2006 18:05

Post by Zippy »

1000101 wrote:The best way would be to use an install maker. That way the modifications to the system can be clearly stated to the user at the time of install and the installer can worry about OS specifics (9x sets environment variable different then NT).
Good point on Win9x. I added that note, "WinNT or newer" to the code. I'm not about to publish code that rewrites autoexec.bat.

@ytwinky

AutoIt is spectacular, and free. What I'm looking for in VISTA that I didn't explain well isn't RUNAS, rather it is OTS (Over The Shoulder) credentials - where I will (can) be prompted for an Admin password when I attempt something that requires Admin access - like installing software.

And then maybe I'll follow my own advice: "never stay logged in as root [Administrator..] longer than necessary". I said that I never had non-root users whack *nix systems, but I did have SysAds whack'em - which eventually forced the global use of SUDO. RUNAS more or less equals SUDO. OTS will hopefully be one step above that - at least easier than logging out/in..

A bit on VISTA UAC/OTS:

http://blogs.msdn.com/uap/archive/2005/ ... 80740.aspx
ytwinky
Posts: 217
Joined: Dec 03, 2005 12:44
Location: MD, Germany

Post by ytwinky »

@Zippy:
Yes, AutoIt is great, I'm active in the german forum(autoit.aufwaerts.de)..
Concerning different accounts: I agree..
..when I surf on the internet, I do it as 'User' with restricted rights..
additionally I have no 'Administrator'-account and no 'Administrators'-group(of course I have, but I renamed them..)
Concerning Vista:
Vista-Check says, I need a new computer..
(I have 'only' 256MB RAM and 'only' 32MB Graphics-RAM..)
..my purse says, I don't need Vista..
(This response would have been much longer in german :D )
Best regards
ytwinky
Post Reply