1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to make Lua modify env-vars

Discussion in 'Support' started by Michael R., Aug 11, 2014.

  1. Michael R.

    Joined:
    Oct 14, 2012
    Messages:
    2
    Likes Received:
    0
    Lua and Env(ronment-Vars).

    Some time ago, I tried mixing .bat-files and .exe-files (from C/C++) code and was disappointed to being not able to use the setenv()-functions, i.e. not being able to set an env-variable in the .exe-file, which could be evaluated afterwards from my .bat-file.

    Now I am wondering, if this could be done in Lua, a scripting language I am interested in, but totally new.

    So I was happy, when I found information, where exactly this issue was adressed and stated, it would work:
    http://jpsoft.com/forums/threads/lua-for-take-command-release-1-0.437

    Unfortunately it turned out, this was kind of a plugin for a former TC-version and the examples in there do not work in TC16.

    So, is there a way to call from within a .bat-file a .lua-file and let it modify some env-vars, the .bat-file-caller can evaluate?

    Or how do you guys pass arguments between a .bat-file and a called script/exe-file? My workaround was to make the exe-file create a new .bat-file, in which the env-var is set (e.g. SET _TMP_ENV=abc) and call it later from within the original-.bat-file.

    Thanks a lot...


    Btw: I was searching for Lua within the TC-forum, but got the message
    The search could not be completed because the search keywords were too short, too long, or too common.
    So might be this issue was already discussed somewhere...
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I'm far from a LUA expert, but as far as I know, basic LUA doesn't have a way to manipulate the Windows environment. However, the WINAPI LUA extension provides this (and much more). Google "LUA winapi" for more info. Here's a little example with TCC's internal LUA support enabled and winapi.dll in TCC's home directory.
    Code:
    v:\> type luatest.btm
    test.lua
    
    v:\> type test.lua
    require "winapi"
    winapi.setenv("foo","bar");
    
    v:\> set foo
    TCC: Not in environment "foo*"
    
    v:\> luatest.btm
    
    v:\> set foo
    bar
     
  3. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
  4. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    You can search the JPSoftware site for three character words from Google as follows;
    Code:
    lua site:jpsoft.com
    Joe
     
  5. Michael R

    Joined:
    Aug 12, 2014
    Messages:
    12
    Likes Received:
    0
    Hello Vefatica,

    thanks for your reply and great to hear, there is a way.

    Trying your example, i.e. executing luatest.btm, I got the messages:

    test.lua
    Lua: E:\temp\temp\lua\test.lua:1: module 'winapi' not found:
    no field package.preload['winapi']
    no file 'C:\TakeCommand\lua\winapi.lua'
    no file 'C:\TakeCommand\lua\winapi\init.lua'
    no file 'C:\TakeCommand\winapi.lua'
    no file 'C:\TakeCommand\winapi\init.lua'
    no file '.\winapi.lua'
    no file 'C:\TakeCommand\winapi.dll'
    no file 'C:\TakeCommand\loadall.dll'
    no file '.\winapi.dll'
    stack traceback:
    [C]: in function 'require'
    E:\temp\temp\lua\test.lua:1: in main chunk
    [C]: in ?


    Indeed, I have no winapi.lua in my TakeCommand directory whereever.
    So, is there a place where winapi.lua (and perhaps other external lua-modules), which are compatible with TC's lua-version, can be downloaded?

    Thanks a lot

    P.S. Sorry for the delay. I had some forum-access-problems
     
  6. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    Follow the links in my post. If you can't find the winapi library by Steve Donovan, I'll post a LUA52.DLL that I built myself after adding os.setenv().
     
  7. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    P.S. The winapi library is a DLL (winapi.dll). When you use "require", Lua looks for a DLL.
     
  8. Michael R

    Joined:
    Aug 12, 2014
    Messages:
    12
    Likes Received:
    0
    Thanks, Vefatica, for the fast replies.

    >> Follow the links in my post.
    Which post do you mean?


    Trying (the first three) winapi.dll-files I found (via Google) on site https://github.com/stevedonovan/winapi/downloads within TCC 16.03.55 x64 Windows 7 [Version 6.1.7601]

    I always get the message:

    test.lua
    Lua: error loading module 'winapi' from file 'C:\TakeCommand\winapi.dll':
    %1 ist keine zul├Ássige Win32-Anwendung
    [Translated: %1 is no valid win32-application].

    stack traceback:
    [C]: in ?
    [C]: in function 'require'
    C:\temp\temp\LUA\test.lua:1: in main chunk
    [C]: in ?


    Thanks a lot
     
    #8 Michael R, Aug 13, 2014
    Last edited: Aug 14, 2014
  9. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    I downloaded https://github.com/downloads/stevedonovan/winapi/winapi-1.4.1-52gcc.zip and it worked on my TCC, but I am using;

    Code:
    TCC  16.03.54  Windows Vista [Version 6.0.6002]
    TCC Build 54  Windows Vista Build 6002  Service Pack 2
    which is 32-bit TCC.

    Joe
     
  10. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I just tried to build winapi for x64 and failed. It may take a lot of work. But I did manage to build a 64-bit version of LUA52.DLL in which I have included os.setenv(). I can't test it on 32-bit Windows. It is attached. The "os" module is built-in so test.lua may not need the "require" statement. And change the winapi.setenv() to os.setenv(). Save your previous LUA52.DLL just in case. I hope to hear that it works. The changes needed to add os.setenv() were minor. Rex can have them if he wants.
     

    Attached Files:

  11. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I (re-)tested os.setenv() in my 32-bit version of LUA52.DLL and it worked correctly. So I suspect it will work in the 64-bit version I posted. Here are my tests, first scripted, then interactive.
    Code:
    v:\> type luatest.btm
    unset /q foo
    test.lua
    set foo
    
    v:\> type test.lua
    os.setenv("foo","bar");
    
    v:\> luatest.btm
    bar
    Code:
    v:\> set zzz
    TCC: Not in environment "zzz*"
    
    v:\> lua -i
    > os.setenv("zzz","foobar");
    > print(os.getenv("zzz"));
    foobar
    >
    ^C
    v:\> set zzz
    foobar
    
     
  12. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I updated the attached file at 21:35 (U.S. EDT). It has a small improvement, and is recommended over the older one. There's also a 32-bit one attached.
     

    Attached Files:

  13. Michael R

    Joined:
    Aug 12, 2014
    Messages:
    12
    Likes Received:
    0
    @vefatica: Thank you so much: I just tried the new lua-test demo with my x64-version of TC and lua52-x64.zip's LUA52.DLL: it works fine.

    I hope Rex will include this in the official version of TC (or extend his version of LUA52.DLL with a similar functionality)...

    A little strange, that WINAPI.DLL does not exist as a 64bit version.
     
    #13 Michael R, Aug 14, 2014
    Last edited: Aug 15, 2014
  14. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I don't know if Rex is building his own LUA52.DLL. The Lua's ability to interact with TCC's environment seems a must when Lua's embedded in TCC. The changes I made appear below. In addition to adding os.setenv() (with SetEnvironmentVariable()) I changed os.getenv() to use GetEnvironmentVariable() so that the two would actually manipulate the process environment instead of a CRT copy of it. If Rex is building LUA52.DLL and knows more about its inner workings than I do, he may improve on this.
    Code:
    // vef 1/25/2014 - loslib.c ~line 115 - revised slightly 8/14/2014
    // added os_setenv (os.setenv) and two-line change to os_getenv
    // also added "setenv" to name/function table syslib[] near line 321
    
    #include <Windows.h> // or ...
    //__declspec(dllimport) unsigned long __stdcall GetEnvironmentVariableA(const char *pName, char *pValue, unsigned long nSize);
    //__declspec(dllimport) int       __stdcall SetEnvironmentVariableA(const char *pName, const char *pValue);
    
    static int os_setenv ( lua_State *L )
    {
       if ( !SetEnvironmentVariableA(luaL_checkstring(L,1), luaL_checkstring(L, 2)) )
         return luaL_error(L, "SetEnvironmentVariable failed");
       return 1;
    }
    
    static int os_getenv (lua_State *L)
    {
       //lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */ /* originally */
       char szValue[32768];
       lua_pushstring(L, GetEnvironmentVariableA(luaL_checkstring(L, 1), szValue, 32768) ? szValue : NULL);
       return 1;
    }
    
    
    // later in loslib.c
    
    static const luaL_Reg syslib[] = {
      {"clock",  os_clock},
      {"date",  os_date},
      {"difftime",  os_difftime},
      {"execute",  os_execute},
      {"exit",  os_exit},
      {"getenv",  os_getenv},
      {"remove",  os_remove},
      {"rename",  os_rename},
      {"setenv",   os_setenv}, // added vef 1/25/2014
      {"setlocale", os_setlocale},
      {"time",  os_time},
      {"tmpname",  os_tmpname},
      {NULL, NULL}
    };
     
    Michael R likes this.
  15. Michael R

    Joined:
    Aug 12, 2014
    Messages:
    12
    Likes Received:
    0
    Is there a way to let the original lua52.dll on it's place and explicitely call a lua-script-file like test.lua with the new (and renamed lua52.dll, e.g. lua52_x64.dll)?
    So these two can coexist. Just in case, there are any incompatibilities between these two...
    Or perhaps also useful, if lua53.dll will be published to be able to define what to use: lua52.dll or lua53.dll...
     
    #15 Michael R, Aug 15, 2014
    Last edited: Aug 15, 2014
  16. w_krieger

    Joined:
    Nov 2, 2008
    Messages:
    176
    Likes Received:
    0
    The people who worked with BartPE, its plugins and other things, learnt a lot about the niceties of setting the Windows NT environment. To counter this, they wrote a number of nifty utilities that work under CMD.EXE etc. Ye see there references to me as 'wendy' or 'os2fan2'.

    Under WindowsPE, the registry environment is read only on IPOL. The environment passed to shells comes from the Winshell program. I used to use nu2menu, which comes with nu2menumsg, which allows you to modify the master environment.

    Another alternative is to use Frank Westlake's CONSET utility, which can read registry settings into the command environment, by injecting it. 4NT can read registry settings to its environment too, but by a different process.
     
  17. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    I don't think so. Why would you want to do that?
     
  18. Michael R

    Joined:
    Aug 12, 2014
    Messages:
    12
    Likes Received:
    0
    1) If the original lua52.dll is updated, user's could have both versions to check easily, if an error is because of not having the original dll or if there is something else going on.
    2) If lua52.dll is upgraded, but a user would not like to upgrade TC yet, he might be able to use the new lua53.dll too.
     
  19. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,934
    Likes Received:
    30
    Without being upgraded, TCC wouldn't run with LUA53.DLL (even if it existed).
     

Share This Page