Thread: Help needed with external call, WinExec() and timer.

  1. #1
    Registered User
    Join Date
    Nov 2001
    Posts
    6

    Question Help needed with external call, WinExec() and timer.

    Greetings!



    My objective is to print the output of "netstat" and "netstat -e" into a file and read from it the data and display it through my program.



    The first problem I encountered is that
    WinExec("netstat -e > tmp.txt", FALSE);
    cannot work because the function does not seems to be able to understand "> tmp.txt".



    The first advice I received is to make a batch file and call it.
    WinExec("batch.bat", FALSE); //batch.bat: netstat-e > tmp.txt
    The problem with this solution is that a thread Winoldap is created upon this call and does not terminates even when the batch file finishes operation(unlike calling an .exe).



    Another problem that I fear I might encounter is that how can I determine the operation to write to the file is finished so that I can read the file?
    Function_To_Write_To_File(); //WinExec("batch.bat", FALSE); -Which has a problem
    Function_To_Read_File();
    A process is created to write the file(an individual thread, I think) and the commands to read the file may be carried out even before the file is written.



    Since I am using timer to refresh the data shown, how can I ensure that there is no multiple call to refresh?
    Let's say I set the timer
    SetTimer(timer, 1000, NULL);
    And on timer, I call a function refresh(); the function refresh() may take more than 1.000 second to finish operation and before it finishes, another call to refresh() is made.
    How do I solve this?



    Please help.
    I am a beginner, please try to explain in as much details as possible.



    Advanced thanks.

  2. #2
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    You could use the standard library function freopen() to re-direct stdout to a file, and if you execute netstat with CreateProcess you can get a handle to the process and use this to establish if it's finished. Something like this -

    Code:
    PROCESS_INFORMATION pi={0};
    	STARTUPINFO si={0};
    	DWORD status=0;
    	si.cb=sizeof(STARTUPINFO);
    	CHAR exepath[MAX_PATH];
    	
    	GetSystemDirectory(exepath,MAX_PATH);
    
    	strcat(exepath,"\\netstat.exe");
    	freopen("c:\\stdout.txt","w",stdout);
    	CreateProcess(sysdir,0,0,0,FALSE,0,
    		0,0,&si,&pi);
    
    	GetExitCodeProcess(pi.hProcess,&status);
    
    	while(status==STILL_ACTIVE)		
    		GetExitCodeProcess(pi.hProcess,&status);
    zen

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    6

    Help still needed!

    Using freopen(), the output of
    printf("Hello!");
    is redirected to the file, however, the output of system("netstat"); does not get redirected to the file (it is still displayed through a MS-DOS prompt window).

  4. #4
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    Sorry that would have only worked in console mode. Try this -

    Code:
    PROCESS_INFORMATION pi={0};
    	STARTUPINFO si={0};
    	DWORD status=0;
    	CHAR exepath[MAX_PATH];
    	SECURITY_ATTRIBUTES sa;
    	sa.bInheritHandle=TRUE;
    	sa.lpSecurityDescriptor=NULL;
    	sa.nLength=sizeof(SECURITY_ATTRIBUTES);
    	
    	HANDLE hStdout =CreateFile("c:\\stdout.txt",GENERIC_READ|GENERIC_WRITE,0 
    		,&sa,OPEN_EXISTING,0,0);
    
    	SetStdHandle(STD_OUTPUT_HANDLE,hStdout);
    
    	
    	si.cb=sizeof(STARTUPINFO);
    	si.hStdOutput=hStdout;
    	si.dwFlags=STARTF_USESTDHANDLES;
    	
    	GetSystemDirectory(exepath,MAX_PATH);
    
    	strcat(exepath,"\\netstat.exe");
    	
    	CreateProcess(exepath,0,&sa,&sa,TRUE,0,
    		0,0,&si,&pi);
    
    	GetExitCodeProcess(pi.hProcess,&status);
    
    	while(status==STILL_ACTIVE)		
    		GetExitCodeProcess(pi.hProcess,&status);
    zen

  5. #5
    Registered User
    Join Date
    Nov 2001
    Posts
    6
    I pasted the codes you have given but it still don't work.
    The file is not written.

  6. #6
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    If the file doesn't already exsist you'll have to change CreateFile() to -

    Code:
    HANDLE hStdout =CreateFile("c:\\stdout.txt",GENERIC_READ|GENERIC_WRITE,0 
    		,&sa,CREATE_ALWAYS,0,0);

    Also if you get this to work and want to prevent an empty console from popping up change CreateProcess() to -

    Code:
    CreateProcess(exepath,0,&sa,&sa,TRUE,DETACHED_PROCESS,
    		0,0,&si,&pi);
    zen

  7. #7
    Registered User
    Join Date
    Nov 2001
    Posts
    6
    Having made the changes, it still doesn't work.

    I replaced call to "netstat" with call to "t.exe", an program written in DOS that makes a sound with the PC speaker and prints some text.
    However, no sound is heard.

    I suspect that there is no execution of the external progam at all.
    stdout.txt is present as a 0 byte file.

    Please help me check the codes.



    The current code is:

    PROCESS_INFORMATION pi={0};
    STARTUPINFO si={0};
    DWORD status=0;
    CHAR exepath[MAX_PATH];
    SECURITY_ATTRIBUTES sa;
    sa.bInheritHandle=TRUE;
    sa.lpSecurityDescriptor=NULL;
    sa.nLength=sizeof(SECURITY_ATTRIBUTES);

    HANDLE hStdout =CreateFile("C:\\stdout.txt",GENERIC_READ|GENERIC_ WRITE,0 ,&sa,CREATE_ALWAYS,0,0);
    SetStdHandle(STD_OUTPUT_HANDLE,hStdout);


    si.cb=sizeof(STARTUPINFO);
    si.hStdOutput=hStdout;
    si.dwFlags=STARTF_USESTDHANDLES;

    GetSystemDirectory(exepath,MAX_PATH);

    strcat(exepath,"\\netstat.exe");

    CreateProcess(exepath,0,&sa,&sa,TRUE,DETACHED_PROC ESS,0,0,&si,&pi);
    GetExitCodeProcess(pi.hProcess,&status);

    while(status==STILL_ACTIVE)
    GetExitCodeProcess(pi.hProcess,&status);

    MessageBox("!");




    So sorry to be such a trouble. But I have been trying to get this done for the past 12 hours. I am beginner in Windows programming, knowing almost nothing about Windows programming.

  8. #8
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    Are you using win9x? If so netstat isn't in the system directory, but the Windows root directory so you'd want to replace the GetSystemDirectory() call with -

    GetWindowsDirectory(exepath,MAX_PATH);

    If this is the cause and you want your program to run on NT and 9x systems you'll want to call GetVersion(); and then call the appropriate function based on the version. I've tried the code on NT and 9x systems and it appears to work fine on both with the above alteration.
    zen

  9. #9
    Registered User
    Join Date
    Nov 2001
    Posts
    6
    The code is a success.

    However, I need to close the file "stdout.txt" to read the data from it (so that I can present the information) and then set it back as the output target of "netstat" (and repeat the cycle).
    How do I do that?
    [The file seems to be close only when the whole program is terminated and not when the CreateProcess() finishes operation.]

    If I make the information refresh automatically, I fear that there is always disk activity while the program is running (Since my output is to a file).
    Is it also possible to "print" the output into memory as text and read from it (instead of opening a file and read from it, I read from an array char ProgramOutput[1024])?

    You have been of very great help to me.
    Thanks a hundred.

  10. #10
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    CloseHandle(hStdout); should close the file. You could disable the refresh functionality until status!=STILL_ACTIVE.
    zen

Popular pages Recent additions subscribe to a feed