Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Problem with Batch Scripts and CreateProcess()

Problem with Batch Scripts and CreateProcess()

Scheduled Pinned Locked Moved C / C++ / MFC
linuxhelpperlsecuritytools
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    neilsolent
    wrote on last edited by
    #1

    Hi everyone I am running the following piece of code on Windows 2000 and XP (except the code below has been simplified with error checking removed). This code spawns a child process, which writes its output to a logfile called child.log. The problem I am having is: if the child process is a command or batch file, then child.log captures output of commands such as "dir", however, for any processes that are launched from the batch script, such as perl.exe, all the output is lost. I don't know where the output is going or why. I suspect I have done something wrong with handle inheritance somewhere.. any ideas?? I don't get the same problem if the child process is some other shell interpreter, such as bash.exe. SECURITY_ATTRIBUTES secAttr; secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); secAttr.bInheritHandle = TRUE; secAttr.lpSecurityDescriptor = NULL; STARTUPINFO startupInfo; ::ZeroMemory((void*) &startupInfo, sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION processInfo; startupInfo.hStdOutput = CreateFile( "child.log", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, &secAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, NULL); startupInfo.hStdError = startupInfo.hStdOutput; CreateProcess( NULL, commandString, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInfo); // Close handle because parent process has no further need for it: CloseHandle(startupInfo.hStdOutput);

    cheers, Neil

    S 1 Reply Last reply
    0
    • N neilsolent

      Hi everyone I am running the following piece of code on Windows 2000 and XP (except the code below has been simplified with error checking removed). This code spawns a child process, which writes its output to a logfile called child.log. The problem I am having is: if the child process is a command or batch file, then child.log captures output of commands such as "dir", however, for any processes that are launched from the batch script, such as perl.exe, all the output is lost. I don't know where the output is going or why. I suspect I have done something wrong with handle inheritance somewhere.. any ideas?? I don't get the same problem if the child process is some other shell interpreter, such as bash.exe. SECURITY_ATTRIBUTES secAttr; secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); secAttr.bInheritHandle = TRUE; secAttr.lpSecurityDescriptor = NULL; STARTUPINFO startupInfo; ::ZeroMemory((void*) &startupInfo, sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION processInfo; startupInfo.hStdOutput = CreateFile( "child.log", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, &secAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, NULL); startupInfo.hStdError = startupInfo.hStdOutput; CreateProcess( NULL, commandString, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInfo); // Close handle because parent process has no further need for it: CloseHandle(startupInfo.hStdOutput);

      cheers, Neil

      S Offline
      S Offline
      S Douglas
      wrote on last edited by
      #2

      So if I understand the issue correctly, you’re creating a file for a batch file to write to right? Well if that’s indeed the case the issue is how you’re creating it.

      neilsolent wrote:

      startupInfo.hStdOutput = CreateFile( "child.log", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, &secAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

      FILE_SHARE_READ Allows other apps to open it read only. Change that to FILE_SHARE_WRITE or close the file before spawning the the child process.


      I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:

      N 1 Reply Last reply
      0
      • S S Douglas

        So if I understand the issue correctly, you’re creating a file for a batch file to write to right? Well if that’s indeed the case the issue is how you’re creating it.

        neilsolent wrote:

        startupInfo.hStdOutput = CreateFile( "child.log", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, &secAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

        FILE_SHARE_READ Allows other apps to open it read only. Change that to FILE_SHARE_WRITE or close the file before spawning the the child process.


        I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:

        N Offline
        N Offline
        neilsolent
        wrote on last edited by
        #3

        Thanks for the suggestion. I tried this out, but it didn't seem to make any difference. To clarfiy, the issue is that, processes launched by the batch file itself do not send any output to child.log. The batch file itself DOES successfully send ouput to child.log. So if the batch file is: dir perl -v exit 0 .. then you can see output from "dir" (because this is a DOS commmand, that does not run as a new process) but not from perl (because this is launched as a new process). Weird ?? :confused:

        cheers, Neil

        S 1 Reply Last reply
        0
        • N neilsolent

          Thanks for the suggestion. I tried this out, but it didn't seem to make any difference. To clarfiy, the issue is that, processes launched by the batch file itself do not send any output to child.log. The batch file itself DOES successfully send ouput to child.log. So if the batch file is: dir perl -v exit 0 .. then you can see output from "dir" (because this is a DOS commmand, that does not run as a new process) but not from perl (because this is launched as a new process). Weird ?? :confused:

          cheers, Neil

          S Offline
          S Offline
          S Douglas
          wrote on last edited by
          #4

          Sorry, I'm even more confused. :-O So you want the output from the perl script written to the log file right? If you run the perl script from the command line does it do what its suppose to? What is the perl script doing? Any reason it has to be done from a scipt and not part of your C++ App? For any of the command line commands redirecting the output from the screen to a file is >Path.To.File ie dir >C:\MyLog.log


          I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:

          N 1 Reply Last reply
          0
          • S S Douglas

            Sorry, I'm even more confused. :-O So you want the output from the perl script written to the log file right? If you run the perl script from the command line does it do what its suppose to? What is the perl script doing? Any reason it has to be done from a scipt and not part of your C++ App? For any of the command line commands redirecting the output from the screen to a file is >Path.To.File ie dir >C:\MyLog.log


            I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:

            N Offline
            N Offline
            neilsolent
            wrote on last edited by
            #5

            Thanks again for your comments. Here's some answers to your questions: So you want the output from the perl script written to the log file right? = Yes. Whatever the program - that is launched by CreateProcess() - does, I want all stdout (and stderr) to go the logfile child.out. If the launched program is a batch script, this includes the output from any new processes (such as Perl) that the script may launch. If you run the perl script from the command line does it do what its suppose to? = Well, there is no Perl script here, I am just getting Perl to return its version statement (-v flag). But yes, Perl does correctly return the version statement if I run the batch script manually. If I replace the batch script with a shell script (bash.exe instead of cmd.exe) it works just fine - the output from Perl goes to child.out. It seems that it only doesn't work if the program launched with CreateProcess() is a batch script. What is the perl script doing? Any reason it has to be done from a scipt and not part of your C++ App? = That is not really relevant, because the main C++ program - that runs CreateProcess() - is supposed to allow the user to run ANY program or script he/she likes. I was just testing that it out with a sample batch script, when I came across this weird problem. I can't know in advance what programs the user may wish to run, and I can't ask them to kindly not launch any new processes from a batch script !! :-) For any of the command line commands redirecting the output from the screen to a file is >Path.To.File ie dir >C:\MyLog.log = Yes, but I am not sure how that is relevant here? The output from the "dir" call DOES goes to child.log as it stands. It is just odd that the output from the Perl call does not. I have concluded that the difference is that Perl.exe is a new process, whereas dir is not. There must be something strange with the startup parameters in the CreateProcess() call, but I just can't think what.. I hope this makes sense, and I hope you can work out what I could be doing wrong, because I am totally stumped!! X|

            cheers, Neil

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups