How to check if application runs from \program files\

654 views Asked by At

Is there a reliable method to check if an application is run from somewhere beneath program files?

If the user installs the application to program files on local machine, we need to put writable files somewhere else to avoid virtualization on Vista and Win7. When installed to a network disk, though, we want to keep these files with the installation for shared access among users.

Today we do an string comparison between startup path and CSIDL_PROGRAM_FILES, but something tells me this is a very unreliable method.

Any smart solution out there? Is there a 'IsRunningFromProtectedFolder( )'-api that I do not know about? Are there any other folders giving the same problems as program files do?

3

There are 3 answers

1
Marius On BEST ANSWER

This is not a terribly good idea, as a user can install it wherever they want to, and then the check might fail. Instead have a checkbox when the user installs the app, deciding if it is installed locally or on a server.

0
Nat On

We allow our users to install anywhere...

If the user has taken the default, and is installed in Program Files, we make the assumption that we need to write to Documents and Settings/Users. Otherwise, we write our data to a folder under the directory the software is in. This of course can still cause problems, and the install does indeed allow people to choose a different data location if they choose to not go for the default.

On top of that, it's a simple ini file change and a copy to move the data.

On start up we detect if we are in the Program Files directory by comparing the value we obtain from SHGetFolderPath(CSIDL_PROGRAM_FILES) with the start of the path the executable is in.

0
Maksee On

As you I also found problems dealing with UAC folder virtualization.I suggest a workaround, it seems that it should work.

It comes from the assumption that elevated processes always use original copies and not the virtualized ones (CMIIW). Also I assume that you setup processed was executed elevated

The idea is to create a "general" process (non-elevated, legacy), that your main installer should run. This process will create a file name in the user chosen folder with a name and contents that both your programs know (for example, test73819704.bin). If the folder virtualized, this file should appear in the user VirtualStore and SHOULD NOT in the original one (from the point of view and privileges of the installer).

So for chosen C:\Program_Files_But_Not_Necessarily and Process-1 (elevated)

  • Process-1 ensures there's no file C:\Program_Files_But_Not_Necessarily\test73819704.bin
  • It launches Process-2 with no elevation
  • Process-2 creates C:\Program_Files_But_Not_Necessarily\test73819704.bin and checks whether it really exists. If exists it would return with a good return code, otherwise with a "failed" one.
  • Process-1 waits for Process-2 and analize the result. If good, checks for C:\Program_Files_But_Not_Necessarily\test73819704.bin, if it exists, go for "Bingo! No virtualization occured", if doesn't exist, "Bad, let's find some other storage place". If the code from the Process-2 is "failed" one, show the user some error message.

Unfortunately I could not test it right now, but I guess it should work and there's a logic behind this, with Process-2 you just emulate the behavior of your main program )