[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: os.execute
- From: Robert Raschke <rrlua@...>
- Date: Wed, 23 May 2007 09:34:28 +0100
Kenneth wrote:
> is it possible to use os.execute() and have it NOT wait for any return
> code, i.e. I don't get those annoying command prompts lingering around
> after I've launched another program.
I wrote some CreateProcess wrappers a while ago to spawn, wait for
finish, and kill procs. They're not tested extremely well, but might
be a basis to explore creating a process that continues even if the
Lua prog has exited.
#include <windows.h>
#include <shlwapi.h>
#include <tchar.h>
#include <limits.h>
typedef struct {
HANDLE hProcess;
HANDLE hThread;
} process_t;
static void
push_last_error(lua_State *L)
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
lua_pushstring(L, lpMsgBuf);
LocalFree(lpMsgBuf);
}
static int
lspawn(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
if (n != 1) {
lua_pushstring(L, "wrong number of arguments to function `spawn'");
lua_error(L);
} else {
/* Inspired by MSDN ms-help://MS.MSDN.vAug06.en/dllproc/base/creating_processes.htm */
STARTUPINFO si;
PROCESS_INFORMATION pi;
LPTSTR szCmdline = lua_tostring(L, 1);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (! CreateProcess(NULL, szCmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
NULL, NULL, &si, &pi)) {
lua_pushnil(L);
push_last_error(L);
return 2;
} else {
process_t *p = (process_t *) lua_newuserdata(L, sizeof(process_t));
p->hProcess = pi.hProcess;
p->hThread = pi.hThread;
return 1;
}
}
return 0;
}
static int
lkill(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
if (n != 1) {
lua_pushstring(L, "wrong number of arguments to function `kill'");
lua_error(L);
} else {
process_t *p = (process_t *) lua_touserdata(L, 1);
luaL_argcheck(L, p != NULL, 1, "'process handle' expected");
if (! TerminateProcess(p->hProcess, 0)) {
push_last_error(L);
return 1;
} else {
CloseHandle(p->hProcess);
CloseHandle(p->hThread);
free(p);
return 0;
}
}
return 0;
}
static int
lwaitfor(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
if (n != 1 && n != 2) {
lua_pushstring(L, "wrong number of arguments to function `waitfor'");
lua_error(L);
} else {
process_t *p = (process_t *) lua_touserdata(L, 1);
DWORD millis = INFINITE;
luaL_argcheck(L, p != NULL, 1, "'process handle' expected");
if (n == 2) {
lua_Number i = lua_tonumber(L, 2);
luaL_argcheck(L, i >= 0 && i < INT_MAX, 1, "'milliseconds' expected");
millis = i;
}
switch (WaitForSingleObject(p->hProcess, millis)) {
default:
lua_pushnil(L);
push_last_error(L);
return 2;
case WAIT_TIMEOUT:
lua_pushstring(L, "timeout");
return 1;
case WAIT_OBJECT_0: {
DWORD code;
if (! GetExitCodeProcess(p->hProcess, &code)) {
lua_pushnil(L);
push_last_error(L);
return 2;
} else {
lua_pushstring(L, "exit");
lua_pushnumber(L, code);
CloseHandle(p->hProcess);
CloseHandle(p->hThread);
free(p);
return 2;
}
}
}
}
return 0;
}
...
lua_register(L, "spawn", lspawn);
lua_register(L, "kill", lkill);
lua_register(L, "waitfor", lwaitfor);
...
C:\tmp> lua50
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> p=spawn("notepad")
> =waitfor(p, 1000)
timeout
> =waitfor(p)
exit 0
> p=spawn("notepad")
> =kill(p)
>
Robby
--
r dot raschke at tombob dot com