Pelles C forum
C language => Work in progress => Topic started by: czerny on February 04, 2012, 12:32:37 AM
-
I have to carry some different compilers with me on an usb stick. I use Geany as IDE.
In order to set a special environment for the compiler in question I wrote a spawn program.
This tool sets a environment variable DRIVE to the actual usb-drive, reads some other environment vars and the exe name from a configuration file (spawn.spn) and starts the exe. The spawn program can be renamed to some other name (some.exe), than it expects a configuration file 'some.spn'.
I would like to here some tipps to improve this or to remove some errors.
czerny
spawn.spn
[FILES]
EXECUTABLE=tst.exe
[ENVIRONMENT]
PATH=%PATH%;%DRIVE%:\C\spawn
BLA=ok
BLUB=something
spawn.c
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <string.h>
#include <tchar.h>
#include <stdio.h>
#define CHUNCK 500
int _tmain(int argc, TCHAR **argv)
{
DWORD flags, size, chars;
TCHAR *p, *buf = NULL, spn[MAX_PATH], exe[MAX_PATH], drive[] = TEXT("DRIVE=?");
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
BOOL ok;
GetFullPathName(argv[0], MAX_PATH, spn, NULL);
p = &spn[_tcslen(spn)-4];
if ('.' == *p)
{
p = &spn[_tcslen(spn)-3];
_tcscpy(p, TEXT("spn"));
} else
_tcscat(spn, TEXT(".spn"));
drive[6] = spn[0];
GetPrivateProfileString(TEXT("FILES"), TEXT("EXECUTABLE"), TEXT(""), exe, MAX_PATH, spn);
size = 8;
buf = (TCHAR *)malloc(size*sizeof(TCHAR));
_tcscpy(buf, drive);
p = buf + 8;
do {
size += CHUNCK;
buf = (TCHAR *)realloc(buf, size*sizeof(TCHAR));
chars = GetPrivateProfileSection(TEXT("ENVIRONMENT"), p, size - 8, spn);
} while (chars + 2 == size - 8);
/*
p = buf;
while (*p)
{
_tprintf(TEXT("%ls\n"), p);
p += _tcslen(p) + 1;
}
*/
si.cb = sizeof(STARTUPINFO);
#ifdef UNICODE
flags = CREATE_UNICODE_ENVIRONMENT;
#endif
ok = CreateProcess(exe, NULL, NULL, NULL, TRUE, flags,
(LPVOID) buf, // new environment block
NULL, &si, &pi);
if (! ok)
{
printf("CreateProcess failed (%d)\n", GetLastError());
return 1;
}
//WaitForSingleObject(pi.hProcess, INFINITE);
return 0;
}
-
Tip for configuration filename:
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
int __cdecl WinMainCRTStartup(void)
{
TCHAR szFile[MAX_PATH];
DWORD dwLen = GetModuleFileName(0,szFile,sizeof(szFile));
lstrcpy(&szFile[dwLen-3], TEXT("ini"));
MessageBox(0, szFile, 0, MB_OK);
ExitProcess(0);
}
EDIT: Or#define UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
int __cdecl WinMainCRTStartup(void)
{
TCHAR szFile[MAX_PATH];
DWORD dwLen = GetModuleFileName(0,szFile,sizeof(szFile));
#ifdef UNICODE
(*(DWORDLONG*)(&szFile[dwLen-3])) = 0x0069006E0069;
#else
(*(DWORD*)(&szFile[dwLen-3])) = 0x696E69;
#endif
MessageBox(0, szFile, 0, MB_OK);
ExitProcess(0);
}
Another tip: size = CHUNCK;
buf = (TCHAR *)malloc(size * sizeof(TCHAR));
_tcscpy(buf, drive);
p = buf + 8;
buf[6] = spn[0];
do
{
chars = GetPrivateProfileSection(TEXT("ENVIRONMENT"), p, size - 8, spn);
if (chars != size - 8 - 2) break;
size += CHUNCK;
buf = (TCHAR *)realloc(buf, size * sizeof(TCHAR));
} while (1);
-
Yes, that's better. Path is complete and independant from the way spawn is called.
But how and why do you use WinMainCRTStartup.
The linker can not find _main.
czerny
-
But how and why do you use WinMainCRTStartup.
The linker can not find _main.
Bad habit for small test programs without CRT.
BTW:
How you think to handle commandline in your program ?
-
BTW:
How you think to handle commandline in your program ?
I do not need this at the moment. But you are right, I should include this.
Ah, I have just seen your 3. tipp. Thank you for that.
czerny
-
This should do it, even with quoted path:
TCHAR *para = _tcsistr(GetCommandLine(), TEXT(".EXE"));
if (para) while (*para && *para++ != ' ') ;
ok = CreateProcess(exe, para, NULL, NULL, TRUE, flags,
(LPVOID) buf, // new environment block
NULL, &si, &pi);
czerny
-
You migh also want to look into the Path???() tools in shlwapi.h In this case:
PathUnquoteSpaces(), PathFindExtension(), PathRenameExtension(), PathRemoveExtension() and PathQuoteSpaces() might be usefull.
-
Thank you tater!