How To get install applications Installation Path using C#


  • Hello All,

    I have a long day yesterday and even at the end of day i got no reasonable solution to my problem.

    What I really need is to get all the Installed applications on the machine using C# and also the Installaion Directory as well, like C:\Program Files\Adobe\ ... etc. What I have achieved so far is that, I have got the list of all the installed apps from registry settings "MyComputer\HKEY_LOCAL_MACHINE\SOFTWRAE\Microsoft\Windows\CurrentVersion\Uninstall" but there is no way to find the installion path of that particular application. Thats what causing me real problems.

    Waiting for the answer and all the suggestions will be highly appreciated.

    Thanks and Regards,
    Wednesday, May 21, 2008 10:51 AM

All replies

  • Look for a string value named InstallLocation. under each key in




    For MSI installations this will often be set for the product, but not for each of the individual components installed with the product.  Unfortunately, this seems only to work for MSI installations; for programs installed using InstallShield or Wise, a different set of entries gets written.  You may be able to use the keys under


    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths


    to find out where specific .exes are located, but this probably isn't as easy as using InstallLocation.



       — Eric —


    Wednesday, May 21, 2008 11:31 AM
  • App Paths is unreliable as most apps don't use it.  It is predominantly for setting advanced app options.


    You should use the Installer API to get the information you want.  It can tell you everything you want to know about the installed apps.  Here is a link to the MSDN documentation on how to enumerate products and their information:


    Michael Taylor - 5/21/08



    Wednesday, May 21, 2008 12:52 PM
  • I have checked that way before but in this case there is no way tio how to map the install application that are in the UNISTALL folder to the executables that are in the APP PATHS folder. Thats the major issue.
    Thursday, May 22, 2008 1:50 PM
  • If the app was installed with MSI then there are MSI APIs that enumerate installed products (MsiEnumProducts). Given the list of product codes you can use MsiGetProductInfo and ask for

    INSTALLPROPERTY_INSTALLLOCATION - that *may* tell you where main install folder if the setup did the right things to get it stored on the system.


    For non-MSI installs there's nothing that will tell you where the main install folder is because there is no standard as to how they are supposed to expose it to programs that want to know it. Plus there may not actually be a main application folder for some apps - everything might be in common files, for example.


    Friday, May 23, 2008 7:40 PM
  • Okay,

    So is there any way that we can map the applications that are present in the Program Files Folder let us say c:\Program Files\AdobeReader or any other application to the EXACT installation name of that particular application. What I will do is to find each folder in the Program Files and for that I have to find the installation Application Name, does this make sense

    Wating for reply.

    Saturday, May 24, 2008 2:46 PM
  • There is no correlation between installed applications and any entries in Program Files, Uninstall registry or anything else.  The installed applications are strictly maintained by WI.  If you want to do any sort of mapping between directory or registry entries then you're going to have to do it manually. 


    I fail to see what you're trying to accomplish.  At one point you wanted the installed apps and now you're talking about PF directories.  They aren't related in any way.  Take any class library for example.  They are likely to go into the GAC or perhaps PF\Common Files.  No PF directory anywhere.  Even those apps that might install into the PF directory doesn't mean they will.  I don't put games or dev tools in PF so trying to map to such directories would fail.


    Please clarify exactly what information you are trying to obtain.  The only way to get a verbatim picture of installed apps is through WI (for those apps that were installed through it, which is most of them these days).  If you want a copy of what Add/Remove programs shows then use the registry path for Uninstall.  This doesn't necessarily correlate to a single installation.  Many installers put multiple entries here.  It will get you the legacy programs as well but keep in mind that not everything under Uninstall shows up in the A/R entries.  There is also not a guaranteed way to map it to an install directory as not every uninstall entry contains the necessary information.


    Michael Taylor - 5/25/08

    Monday, May 26, 2008 3:11 PM
  • Hello,

    Actually what I want to accomplish is an Interrupt Application, what that will do is that, it will have a list of installed application that are on a particular machine and as soon as an application that will come that is in my monitoring list, that particular application will be interrupted and my application will start the processing. So, to maintain an initial list that which apps are installed on the computer and what are there respective processes and executable names . ..  I have to do all this.

    If you can propose any other solution to this then please suggest. As I have tried to explain what I really want to do.

    Thanks and regards,
    Mustafa Jalil.
    Tuesday, June 03, 2008 11:41 AM
  • I don't think what you want is possible under Windows.  Even if you could get it to work I suspect it would only work for a few select apps or perhaps only very specific machines.  There are quite a few problems that you would need to resolve.


    There is not necessarily a single program that relates to each installed app.  VS, for example, has many programs.  None of these can be magically obtained via the installer or the registry.  The best you can come up with is a list of installed files.  Some apps don't even have an installer.  .NET apps are fond of xcopy deployment.  In this case there is no installer.  Making this even more difficult, some apps have subprograms embedded within them.  This makes getting access to the actual file really difficult.  Games and Process Explorer do this.


    Ultimately I think your generalized goal will fail because there are too many variables.  You might be able to get it to work in a few select cases but I don't think it'll work for general cases.  If you are interested in limiting the applications that can be run on a machine then you should consider looking into group policies instead.  At one point GP could limit the programs that could run on a machine.  Effectively it was just a list of processes that could be started.


    Michael Taylor - 6/3/08



    Tuesday, June 03, 2008 1:06 PM
  • Hi all!

    Sorry if this is not the forum for my question but I think is very related. I want to find out/ to get the full directory path from where a "setup.exe" is executed so that I could look for an XML file in that location.

    Hope someone had met this "black" situation before and could enlight me because I've spent hours looking for a solution... Any help will be greatly appreciated!

    Tuesday, November 04, 2008 11:55 AM
  • MSI defines many properties automatically that you can use.  They are defined here:


    SourceDir is the directory where the setup resides.  It is only available during installation. 


    Michael Taylor - 11/4/08

    Tuesday, November 04, 2008 2:41 PM
  • Hello Michael,


    Thanks for your reply. I've already looked at SourceDir property but I can't just figure out where/how to get it.


    I tried to get it like this:


    string currentDir = this.Context.Parameters["SourceDir"];

    but that doesn't work. I read that if you want to get this property you prior need to call ResolveSource, which one, needs to be called after the CostInitialize action. I tried to find these methods but I couldn't find them inside my class derived from Installer class. (SetSecurity project from MS, SetSecurity.cs more exactly). So, my question is, where I could find these methods or how could I easily access [SourceDir]? I need to override them? If so, why I could not see them (ResolveSource) when the intellisense appears and helps me to override the methods within Installer class.


    Any link or ideea will mean so much right now!


    Thanks and waiting for a response,


    Tuesday, November 04, 2008 3:07 PM
  • Ahh your creating an Installer class.  This is quite a bit different than creating a setup project.  Setup projects use MSI to install applications.  An Installer class doesn't use MSI although it can be used inside a setup project.  There is no correlation between an Installer class and setup projects.


    Normally an Installer class is invoked via InstallUtil.  InstallUtil works on the basis of an assembly rather than a setup project.  Therefore the best you can hope to get is the path where the assembly is that is being installed.  Unfortunately the Context dictionary is initialized by the host and doesn't contain any documented values.  However the property assemblyPath is known to be included and it contains the full path to the assembly being installed.  That probably doesn't have any correlation to the setup though as the installer (if invoked via a setup project) would be run against the installed assembly rather than the source assembly.


    Note that my experience has shown that VS setup projects do use Installer classes internally but I'm not sure if it just uses reflection to suck the information out when you add an assembly or whether it actually invokes the installer at runtime.  Irrelevant you won't have access to the setup.exe directly.  You could hoever use Process.GetCurrentProcess to get the current process'es information from which you can get the path.


    Michael Taylor - 11/4/08

    Tuesday, November 04, 2008 3:46 PM
  • Hi again Michael!


    Thanks for details.


    I could say that I've tried already Process.GetCurrentProcess(). I tried to use it in OnBeforeInstall method, but when I "get" at this method's level, the setup already is "taken"/executed by MsiExec and then the process (setup.exe dissappears - the one that I need) becomes msiexec.exe, who's path points to system32 so I can't get the relevant path to the directory where the setup.exe is double clicked / executed.

    Should I try in the Commit method? Are there any places (methods) where I could maybe get the path to setup.exe before the almighty MsiExec comes and "takes" the lead? :-)

    I've even tried to display the arguments' list of msiexec (iterated through Context.Parameters.Keys and Context.Parameters.Values), it seems that all are related to [TARGETDIR] and System32 and no one gave me the path I need. It's logical, of course, being that way, but I thought that maybe, maybe I missed something... but no...

    I will have a look again at all the methods, maybe there's something I've missed till now.

    Thanks for your advices again!




    Tuesday, November 04, 2008 6:06 PM
  • Without seeing what you passed to CustomActionData in your installer class I don't know if :

    string currentDir = this.Context.Parameters["SourceDir"];


    will work or not. If I were you I'd do this:

    1) In your installer class Install method, in CustomActionData, put /org=[OriginalDatabase]

    2) Look at Context.Parameters["org"]. You should see the full path to the installing MSI file. Just strip that name off foe the path to the containing directory.



    As you've discovered, installer classes run in an msiexec.exe process, and you cannot rely on paths or user registry data being what you might expect.


    Thursday, November 06, 2008 12:40 AM
  • Hello Phil!

    Thanks for your reply! I will check your solution when I'll get the time and post back a reply! Till then, have a nice weekend!

    Friday, November 14, 2008 9:19 AM
  • Hi Mustafa,
        Did you find any answer for this problem?
    Monday, March 30, 2009 4:16 PM
  • will work or not. If I were you I'd do this:

    1) In your installer class Install method, in CustomActionData, put /org=[OriginalDatabase]

    2) Look at Context.Parameters["org"]. You should see the full path to the installing MSI file. Just strip that name off foe the path to the containing directory. 

    In CustomActionData, put   /sd="[SourceDir]\"
    Look at Context.Parameters["sd"].

    It's Work
    Friday, January 29, 2010 1:39 PM
  • All of examples about CustomActionData transferr described in MSDN is about

    But In the case of C#, I can't get CustomActionData using like this.Context.Parameters["sd"] or Context.Parameters[""sd"].

    Because VS 2005 occur error saying "Keyword 'this' is not valid in a static property, static method, or static field initializer ".

    Of course, InstallerClass property set true( I think install program must make InstallClass instance to use "this" keyword at referencing project InstallClass method. but it didn't work.)

    Where is exact answer for C# CustomActionData?
    Saturday, February 06, 2010 5:43 AM

  • I spend 4 days to solve install problem.

    I solved my require through registers setting.
    Then after, VS2005 accept Context.Parameters["sd"].

    So I have dual channel to communicate parameter between install MSI and application.

    I don't understand what happened..

    Walkthrough: Creating a Custom Action  at

    is very unkindable description.

    Monday, February 08, 2010 8:28 AM
  • @CoolDadTx

    "I don't think what you want is possible under Windows" ...True dat.

    Sorry to be a troll, and so long after this thread started, but this is funny. I have an MSI and have been looking for a solution to this... I just find it Ironic and have to comment:

    1 - MSI is an installer tool that is so wildly complex as to bring it to the very precipice of "useless" (proof = the existence of many tools to un=screw the MSI after it's built). Options like "Just f**king uninstall the current one, no matter what f**king version it is" don't exist, leaving the developer in a maze that, more often than not, end it the vicious "you can't install this" -> "you can't uninstall this" loop.

    2 - Yet, despite this obscene and unnecessary complexity, the MSI doesn't even fill in the "InstallLocation" key. LOL!!! x 10000000

    I can only infer from this and many other similar "we needed to add 8.7x10^9 options, unless they were the ones that had any common sense" experiences with MS tools that the developers at Microsoft at tortured and oppressed souls who will not cross their masters by daring to draw lines in the sand about use models. If any such poor wretch is reading this, we in the real world want to help you! It's OK to say to us "Sorry, I won't split what should be a boolean into three GUIDs and a state machine. If you need a specific weirdo problem solved, go write the app yourself." Please listen. Pretty please?

    Tuesday, December 27, 2011 3:52 PM