Executing of batch file

I want to execute one command using batch file but non of below code is working where Please tell me where I am going wrong,

Following are codes for executing batch file, First trial:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
    if( !CreateProcess( NULL,   
        "cmd /C  sa.bat",        
        NULL,         
        NULL,         
        FALSE,        
        0,            
        NULL,           
        NULL,           
        &si,            
        &pi )           
        ) 
    {
        printf( "CreateProcess failed (%d)\n", GetLastError() );
        return FALSE;
    }
    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    return TRUE;

Second trial :-

system("cmd.exe /C sa.bat");
Third Trial :-

_execlpe("cmd", "/c", "sa.bat", static_cast<char*>(0));
Fourth Trial :-

WinExec("sa.bat",SW_SHOWNORMAL);
Fifth Trial :-

ShellExecute(GetDesktopWindow(), "sa.bat","", NULL, NULL, SW_SHOWNORMAL);

Non of above code is working for me but when open same batch file using double click it work like I expected.

Following is content of the file,

C:\windows\system32\wusa /uninstall /kb:2718695 /quiet /forcerestart

Command use to uninstall internet explorer 10 an install internet explorer9.

Any help ,link ,block of code are most welcome.
You don't seem to be filling in the STARTUPINFO record.

The program name is cmd.exe, not cmd.
@aryanLohia

Your code works ok for me, if I ensure that the batch file (in my case, hello.bat) is in the working directory (see below for test program).

- You don't need to provide an extension for cmd, but you should.

- STARTUPINFO only needs the cb member to be set, for the default case.

I think your problem is simply that the batch file is not in the right place for you code to just find it.

But what you are doing is bad practice, esp. from a security point of view.

If you tell Windows to run "cmd", it will:

- first look for cmd.exe, cmd.com, cmd.bat, and cmd.cmd (in that order)

see Path
http://technet.microsoft.com/en-us/library/bb490963.aspx

- it will look for the file in the working directory and then search the path

also see Path

- if a path has spaces in it, and it is not quoted, then it will try the whole path first and then the different bits of it (using the extension rule above)

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

From CreateProcess function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

Which allows people to swap the regular cmd.exe for some evil (e.g.) cmd.com.

So you should provide the full path, quoted and using the extension to the cmd.exe file and also to your batch file. See below for repaired version.

Note that if the code is for your own use, assuming that Windows is installed in C:\Windows is fine. But for "real" code you should not make this assumption. Instead, you should use the GetSystemDirectory function for find out where cmd.exe is located.

GetSystemDirectory function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724373%28v=vs.85%29.aspx

(There are other ways to do this, but this is probably most appropriate in this case.)

Andy

Version 1 -- your code

(Which works for me if hello.bat is in the working directory...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <windows.h>
#include <stdio.h>

int main()
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
    if( !CreateProcess( NULL,
        "cmd /C  hello.bat",
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi )
        )
    {
        printf( "CreateProcess failed (%d)\n", GetLastError() );
        return FALSE;
    }
    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    return 0;
}


Version 2 - with full, quoted paths, etc.

(Gets actual system path and build required command line string. Also tweaked to build either Ansi or Unicode, for _TCHAR fans...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int main()
{
    const TCHAR batchFilePath[MAX_PATH] = _T("W:\\Test\\hello.bat");

    TCHAR systemDirPath[MAX_PATH] = _T("");
    GetSystemDirectory( systemDirPath, sizeof(systemDirPath)/sizeof(_TCHAR) );

    // path to cmd.exe, path to batch file, plus some space for quotes, spaces, etc.
    TCHAR commandLine[2 * MAX_PATH + 16] = _T("");

    _sntprintf( commandLine, sizeof(commandLine)/sizeof(_TCHAR),
        _T("\"%s\\cmd.exe\" /C \"%s\""), systemDirPath, batchFilePath );

    STARTUPINFO si = {0}; // alternative way to zero array
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi = {0};

    if( !CreateProcess( NULL,
        commandLine,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi )
        )
    {
        _tprintf( _T("CreateProcess failed (%d)\n"), GetLastError() );
        return FALSE;
    }

    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    return 0;
}


And for completeness, hello.bat

1
2
@echo off
echo Hello batch world


Output (running from Visual Studio)

Hello batch world
Press any key to continue . . .

Last edited on
Topic archived. No new replies allowed.