News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

spawn

Started by czerny, February 04, 2012, 12:32:37 AM

Previous topic - Next topic

czerny

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;
}


TimoVJL

#1
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);
May the source be with you

czerny

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

TimoVJL

#3
QuoteBut 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 ?
May the source be with you

czerny

#4
QuoteBTW:
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

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

CommonTater

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.


czerny