What should COMSPEC and PATH environmental variables be to locate the command-interpreter, using system()?

26,703

Solution 1

The environment variables are inherited when running a process, including system(...) call. Unless there is something weird going on, usually running %windir%\system32\cmd.exe should do the trick, it should expand the environment variable, unless you can use the API to get the windows directory 'GetWindowsDirectory'. See here for an example from the MSDN.

Edit: IIRC, COMSPEC environment variable, if done on the command line

> echo %COMSPEC%
C:\WINDOWS\system32\cmd.exe

You got a bad pointer, because it is not probably set up, the above echo command should prove that, if you get no output, it is not set, right click on 'My Computer', left-click on 'Properties', a dialog with tab-pages appear, click on 'Advanced', look for 'Environment Variables'...see the two screenshots here...

Also I should point out that you are setting the environment variable temporarily, hence it will not see the 'COMSPEC'....it is not permanent, the only permanent way to do it is follow the screenshots...

I am trying to get the screenshots in place....

alt text

alt text

Edit#2: Just to point out this, when you set the Environment variable here, that is temporary - not permanent!

if (! SetEnvironmentVariable("COMSPEC", "C:\\WINDOWS\\system32\\cmd.exe") )
 {
    printf("SetEnvironmentVariable failed (%d)\n", GetLastError());         
 }

 //r = system("dir c:\\");
 r = CreateProcess("dir.exe", NULL, NULL, NULL, TRUE, NULL, 
    NULL,     // inherit parent's environment 
    NULL, &si, &pi);

When using the call CreateProcess, it is bound to fail, look at the comment "inherit parent's environment", that cannot happen as the environment was set up temporarily. Have you tested the simple echo command here. Something is wrong as to why the COMSPEC variable is not set..after setting it permanently - you will need to reboot the machine for it to work. Then the echo command above should show the value for that environment variable, and in turn, this

argv[0] = strdup(_tgetenv(_T("COMSPEC")));

should return a proper pointer...by the way, I think that should be strdup'd also...

Edit#3: Whoops I noticed when I had '&pi' used, it came up as a pi symbol instead!...duh, that's amended now...also I have amended this 'argv' code here:

argv[0] = _tcsdup(_tgetenv(_T("COMSPEC")));

Solution 2

Start + Control Panel, System, Advanced, Environment variables. Select Path in the System variables section, Edit. At the very least it should look like this:

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem

Ask more questions about this at superuser.com

Share:
26,703

Related videos on Youtube

T.T.T.
Author by

T.T.T.

Updated on March 09, 2022

Comments

  • T.T.T.
    T.T.T. about 2 years

    Are the OS (XP) environmental variables the same used in a process running from visual studio .NET C++?

    It seems the command interpreter is not found:
    When using NULL as the command, system() returns 0 and with command - ENOENT Command interpreter cannot be found.

    In windows (System->Environmental Variables), COMSPEC contains the path to cmd.exe
    PATH does not.

    What should PATH be?

    Other than this, not sure why it can not find the interpreter.

    Any suggestions are appreciated. Thanks.

      if( system("tail -500 log.txt") == -1)
      {
          //Error calling tail.exe on log 
          //errno is a system macro that expands int returning
          //the last error. strerror() converts the error to it's
          //corresponding error message. 
          printf("Error calling tail.exe with system(): %s",strerror( errno ));
    
      }
    

    EDIT1
    Stepping into system() argv[0] = _tgetenv(_T("COMSPEC"));returns a bad pointer. Being this is a cgi executable, the COMPSEC is not properly set or inherited from the OS.
    I now set COMSPEC before the process is started and use CreateProcess() as in example 2

    However, create process still returning 0? Getting closer. See any issues with this? Thanks.

     if (! SetEnvironmentVariable("COMSPEC", "C:\\WINDOWS\\system32\\cmd.exe") )
     {
        printf("SetEnvironmentVariable failed (%d)\n", GetLastError());         
     }
    
     //r = system("dir c:\\");
     r = CreateProcess("dir.exe", NULL, NULL, NULL, TRUE, NULL, 
        NULL,     // inherit parent's environment 
        NULL, &si, &pi);
    

    EDIT 2
    SetEnvironmentVariable() did not work. However, putenv does.
    _putenv( "COMSPEC=C:\\WINDOWS\\system32\\cmd.exe" ); // C4996
    Not sure what the difference is...?
    Now that this env var is set, any request on the cgi app from the browser gives the option to save the cgi.exe instead of executing it.. Not sure why this has changed based on this env var?

  • T.T.T.
    T.T.T. about 14 years
    ok thanks. It looks right?? C:\>echo %COMSPEC% C:\WINDOWS\system32\cmd.exe ? It is also set correctly in the advanced tab....
  • T.T.T.
    T.T.T. about 14 years
    When it searches for COMSPEC in System() it is not found, even when just set before. I think this being a cgi application is throwing something off....
  • T.T.T.
    T.T.T. about 14 years
    Example 2 here (msdn.microsoft.com/en-us/library/ms682009%28VS.85%29.aspx) sets a value for the child process to inherit this way, which is why I did this. Even if it is temporary, shouldn't the child process inherit the parent env during its life? See lpEnvironment (msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) As far as setting the var permanently, if I go to my windows settings I see it's path to cmd.exe, is that permanent?
  • t0mm13b
    t0mm13b about 14 years
    @Tommy - that is permanent in the windows settings...but to quote from MSDN 'Each process has an environment block associated with it.' so why the duplication anyway? Strange....and yes in theory, the child process should inherit the parent env, but the grandparent env would be the system wide setting...understand?
  • T.T.T.
    T.T.T. about 14 years
    Yes I hear you. Still leaves me wondering why my app does not inherit the system env. The only thing I can think is because it is a cgi application and does not receive the normal env but the env from the browser, which is why I tried to add the COMPSEC
  • T.T.T.
    T.T.T. about 14 years
    Yes, the echo of %COMSPEC% in the cmd prompt displays the path to cmd.exe
  • t0mm13b
    t0mm13b about 14 years
    hmmm...can you show the code for the cgi app on pastebin if it's too big to be posted here?
  • T.T.T.
    T.T.T. about 14 years
    Unfortunatel I can't as it is for work. however, it is a basic cgi app in c and as soon as it runs into putenv() for COMPSEC it asks if I want to save the cgi.exe I'm thinking it has to do with the web server (GoAhead) settings. Looking at it but not sure where this would be happening....
  • t0mm13b
    t0mm13b about 14 years
    @Tommy: Ok...there may be a restriction on the CGI in the sense that environment variable access is limited...?! I will check out the website to see if there's anything I can glean on to help you crack this...
  • Shubham Srivastava
    Shubham Srivastava about 2 years
    Strange, the screenshots show the Ukrainian flag with NO WAR on it. For the answer edited two days back from today.