How to make Lua modify env-vars

Oct 14, 2012
2
0
#1
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
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
 
Aug 12, 2014
13
0
#5
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
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
 
Aug 12, 2014
13
0
#8
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
 
Last edited:
#9
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
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
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.
 

Attachments

#11
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
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.
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.
 

Attachments

Aug 12, 2014
13
0
#13
@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.
 
Last edited:
#14
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}
};
 
Likes: Michael R
Aug 12, 2014
13
0
#15
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...
 
Last edited:
Nov 2, 2008
180
0
#16
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
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...
I don't think so. Why would you want to do that?
 
Aug 12, 2014
13
0
#18
Why would you want to do that?
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.