Important: Please read the Qt Code of Conduct -

"Program files" from environment variable in .pro file

  • Hi, everyone!

    I've switched from an italian Windows to an english Windows.
    In italian version, environment variable "ProgramFiles" is set to "C:\Programmi". I have no problem in using it in my .pro file, like

    INCLUDEPATH += $$(ProgramFiles)/OpenCV2/include

    Everything works fine here. Compiler find headers, linker find libs.

    In the english version, "ProgramFiles" is set to "C:\Program Files". Here, I can't use the environment variable in the .pro file. I think it's due to the space. I've added quotes, I've used the quote() macro, but everything without success. Compiler can't find headers and linker can't find libs.

    What am I missing?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    The only thing you missed is the warning: avoid spaces in path especially on Windows, it's always been a source of trouble.

    However, I've only experienced this problem when linking not with INCLUDEPATH.

    Can you show what you get with message($(ProgramFiles)) ?

  • @SGaist , thanks for your answer.

    I absolutely agree with the "no spaces in paths" rule. But since Microsoft's guys decided to name the most important folder in the OS "Program Files", we have to deal with it.

    About your question, message($(ProgramFiles)) returns

    Project MESSAGE: C:\Program Files (x86)

    Quite interesting... So probably the problem is not the space, but the fact that ProgramFiles has a different value to what I expected. Well, not that I expected to have something fancy: just the value set in the variable, the returned from command promt, too.
    Also, it displays this path both when configured for x86 and x64 (have a doubt about it, so I've tested).

    Sooooo, here comes the next question.
    How to get x86 and x64 Program Files path using environment variables?

    I'm almost forced to use environment variables for this, since I share the project with people that use different languages for the OS, and both x86 (where you have a single Program Files folder) and x64 (where you have two different Profram Files folders) systems.

    Thanks again!

  • Lifetime Qt Champion

    If your application is 32bit then you can just use ProgramFiles - it already points to the right directory.
    I don't know how to get the x64 directory

  • Found an interesting discussion on StackOverflow, where an user said this:

    So from a 64-bit process on a 64-bit system you would get C:\Program Files, from a 32-bit process on a 64-bit system you would get C:\Program Files (x86), and from a 32-bit process on a 32-bit system you would get C:\Program Files.

    So I suppose my Qt Creator (or qmake?) is 32 bit, so it reads "C:\Program Files (x86)" from "ProgramFiles" environment variable. And there is probably no way to get "C:\Program Files" path...

  • Moderators

    If you always want the "Program Files", no matter if your process is 32 or 64 bit then there's another environment variable defined by the WOW64 subsystem: ProgramW6432. It will always return "Program Files ". Just make sure that this redirection bypassing is really what you want.

  • @Chris-Kawa , looked like a good solution but awfully it is not defined in x86 systems.
    I need an environment variable, say "DatProgramFiles", that behave like this:
    English system, x64: $(DatProgramFiles) = "C:\Program Files"
    English system, x86: $(DatProgramFiles) = "C:\Program Files"
    Italian system, x64: $(DatProgramFiles) = "C:\Programmi" (similar with other languages)
    Italian system, x86: $(DatProgramFiles) = "C:\Programmi" (similar with other languages)

    Looks like the only way is to add a custom environment variable...

  • Moderators

    Looks like the only way is to add a custom environment variable...

    Nah, you can check if the variable is defined or not. Something like this:

    IS64BITSYSTEM = $(ProgramW6432)
    isEmpty(IS64BITSYSTEM) {
        message(This is 32 bit system)
        INCLUDEPATH += $(ProgramFiles)\.....
    !isEmpty(IS64BITSYSTEM) {
        message(This is 64 bit system)
        INCLUDEPATH += $(ProgramW6432)\.....

  • @Chris-Kawa THANKS! This was really useful!
    I've used your solution to check for VS version, too. I made something like this:

    IS64BITSYSTEM = $$(ProgramW6432)
    # Get Program Files folder, given x86/x64 architecture
    !isEmpty(IS64BITSYSTEM) {
      PROGRAM_FILES_SYS = $$(ProgramW6432)
    isEmpty(IS64BITSYSTEM) {
      PROGRAM_FILES_SYS = $$(ProgramFiles)
    # Get lib folder given most recent VS version
    !isEmpty(VS10AVAILABLE) {
      VC_OPENCV_DIR = "vc10"
    !isEmpty(VS11AVAILABLE) {
      VC_OPENCV_DIR = "vc11"
    !isEmpty(VS12AVAILABLE) {
      VC_OPENCV_DIR = "vc12"

    This way, the sequential check will set the variable VC_OPENCV_DIR given the most recent VS version found. Then I can do something like this

    win32:CONFIG(release, debug|release): LIBS += -L$${PROGRAM_FILES_SYS}/OpenCV2/x86/$${VC_OPENCV_DIR}/lib/ -lopencv_core2410

    So on every system it will look in the correct Program Files folder and it will take the right build.


    I'll take advantage of your knowledge a little more.
    What's the difference between using a single '$' (e.g. $(ProgramFiles)) instead of a double '$$' (e.g. $$(ProgramFiles))?
    Using a single one, as you suggested, I can't access the variables; using double '$$' I can access variables. As an example, $(ProgramW6432) is empty; $$(ProgramW6432) is "C:\Program FIles". Same behavior for local variables.

  • Moderators

    See here for qmake language reference.
    Basically the $ $ operator applied to environment variables will be evaluated at qmake run, while the $ when the generated makefile is processed.

Log in to reply