Is there a restriction of QProcess under Windows 7?

  • Moderators

    I am using 7z.exe started through QProcess in one of my applications.
    void Process::sltProcess ()
    QProcess process;
    QString cmd = "7z.exe";
    process.setStandardOutputFile ( "test.out" );
    process.start( cmd );
    process.waitForFinished ();
    From command prompt the exe may be started anywhere since the 7z-folder is in the PATH environment. The folder is "C:\Program Files\7-Zip". Since the folder contains a space the folder is included with quotation marks in the path settings. AFAIK most installers do it this way when the folder path to be included contains a space.

    Unfortunately, it did not work lately. I had to include the complete path with the exe in order to make it work. However, it did work in the past, therefore, I started to search for the problem and found today that removing the quotation marks in the environment variable for PATH was solving the problem.

    My OS is windows 7 64 bit. Using MSVC 2005 and Qt creator with MinGW 4.7.2

    Can someone confirm this?

    [Edit] This is with Qt 4.7.2 and 4.8.3.

  • If you run an application from the console, the shell interpreter (cmd.exe) looks for the program to launch. And it indeed scans through the path's in the PATH environment variable. However QProcess internally uses CreateProcess() from the Win32 API to create the process. It does not use/invoke "cmd.exe" for this purpose.

    The docs clearly say:
    [quote]The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification. The function will not use the search path. This parameter must include the file name extension; no default extension is assumed.[/quote]

    For details:


    IMO relying on the PATH environment variable for your software to work is really bad practice! What if somebody else will install a newer/older version of 7z that breaks compatibility with your app and prepends that path to PATH? Or what happens if somebody installs a completely unrelated program that happens to be called "7z.exe" and prepends that path to PATH? Your application will fail horribly :-(

    I would put all tools you need into a subfolder (e.g. "utils") inside your applications install folder. Then use:
    @cmd = QString("%1/utils/7z.exe").arg(QCoreApplication::applicationDirPath());@

  • Moderators

    Thanks for your reply.

    Obviously it does search the path. Otherwise it would not be possible to locate 7z.exe in this case.

    For larger applications it may become impracticable to have always a copy. For small tool like gzip and 7z it is easier, but also a pain to have extra copies. Especially during development I am clearing the folder with the exes which could provide another problem. So both ways have their odds.

    However, I need to rethink my strategy anyhow when the environment path is unreliable.

  • Well, for larger applications where you cannot have your own copy, I see two solutions:

    • Make a custom environment variable for you app, like MYAPP_TOOL_PATH where the myapp "MYAPP" prefix is unique to your application and the "TOOL" part is unique to the individual tool. Then, at runtime, read that path via getenv(). Advantage: Nobody will mess with your environment variables. Also it will be easy to build the complete path, because MYAPP_TOOL_PATH will contain a single path.

    • Look up the install location of the tool from the Registry. Pretty much any tool that gets "installed" will store it's install path somewhere in the Registry. You will only need to look up the correct reg key.

  • Moderators

    IMO going through with a separate environment setting has some advantages.
    Messing around with registry isn't really what I am up to.

    BTW according to "this": one should better use qgetenv

    Thanks again for your suggestions.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.