2

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?

Kromster
  • 7,181
  • 7
  • 63
  • 111
Vegar
  • 12,828
  • 16
  • 85
  • 151
  • 2
    I don't care which language. This is a windows problem not an language problem. The problem should be the same what ever language you use. – Vegar Dec 09 '09 at 12:40
  • 2
    Don't guess what the user might need, give them the option to change the directory for data files. For example we have a customer whose systems have read-only C drives for all standard users. OTOH IT may need to decide whether data files of a local installation are to be shared between multiple users of that system or not. Location of data files is a policy decision and need not have anything to do with the installation path. – mghie Dec 10 '09 at 09:17
  • Interesting - I'm starting to have conceptual issues like this, moving my stuff to Vista/Win 7. So this is the bit where I grab a coffee and sit back, eagerly awaiting the thoughts and suggestions of StackOverflow. :-) – robsoft Dec 10 '09 at 10:23
  • 1
    @mghie: The problem with giving choices, is that most of our users don't have the knowledge to make a choice. But I can't see any other good solution, though, and I have nearly convinced the other decision takers that it is impossible to detect what's right. For know, we have settled on asking the user during installation if it is a local, one-user installation, a shared intallation on server, or an installation for terminal services. We are unsure about the last one though. Any way, we have documented tweaks for knowledged sys.admins. @robsoft: enjoy your coffee ;-) – Vegar Dec 10 '09 at 11:18
  • @Vegar: The key to giving a choice is to have a sensible default. I read the location from the registry, but default to the My Documents location. The user can then have files here if they don't care, or they can be changed in the UI if someone wants to. – mj2008 Dec 10 '09 at 13:54

3 Answers3

3

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.

Marius
  • 57,995
  • 32
  • 132
  • 151
  • We have to deal with terminal serivces too, which makes the case a little more complex... – Vegar Dec 10 '09 at 11:19
0

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.

Nat
  • 5,414
  • 26
  • 38
0

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 )

Maksee
  • 2,311
  • 2
  • 24
  • 34