4

I found a snippet of code explaining how to use System.Diagnostics.Process.Start to run an external program in C#. The snippet shows running cmd.exe, which is in the path.

Let's assume that there is some external program (Beyond Compare for example). I don't know if it is installed on the PC. How can I check if this program is installed using C#? If the program is installed, I would like to find the path so that I can launch it.

Aidan Ryan
  • 11,389
  • 13
  • 54
  • 86
geek
  • 2,677
  • 4
  • 23
  • 21
  • 2
    There are a couple of different things you can do, check the registry for any added registry keys(HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall). Or assuming most programs are installed in the Program Files directory, you can get the Program files path by using the system variable %ProgramFiles%. What exactly are you trying to accomplish? I think the downvote was done because your question was not clear. – roymustang86 Sep 17 '11 at 00:53
  • 1
    Removed the code sample because it was misleading. – Aidan Ryan Sep 17 '11 at 01:04
  • @Aidan Ryan: why is the code sample misleading? It at least indicates that the OP knows how to run a program from C# (thus preempting a spate of answers along the lines of "here's how to use Process.Start()"), but wants to know how to expand that to finding an installed program and then running it. – siride Sep 17 '11 at 01:07
  • 1
    http://stackoverflow.com/questions/908850/get-installed-applications-in-a-system – Mehdi Hadjar Sep 17 '11 at 01:12
  • 1
    @siride Just a mention of Process.Start is enough. Sample was 80% of the body of the questin. – Aidan Ryan Sep 17 '11 at 01:14
  • 2
    @roymustang86 and @MehdiHadjar refer us to iterating the list of installed programs under `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall` -- that's the closest to an answer to the actual question. It will at least allow you to detect if the program is installed, **IF** you know its Program Code GUID or DisplayName. From there, if InstallLocation is set you can at least know the path where the executable *may* reside. You still are required to know the actual executable filename and it requires more rights than app launch. (@roymustang86 - be careful with %programfiles% on 64 bit systems) – Aidan Ryan Sep 17 '11 at 01:22
  • Yeah, I actually have run into that problem while writing auto update program for a 32 bit application. When installed on a 64 bit system, they were installed in the ProgramFiles(x86) folder, and it kept downloading the file over and over and failing. – roymustang86 Sep 17 '11 at 01:33

4 Answers4

5

I found this question, which directed me to this this article. I've modified the source for readability, and to solve your problem specifically (note that I've guessed the description and executable name of Beyond Compare.)

You can call it like this, from your main:

string path = FindAppPath("Beyond Compare"); 
if (path == null)
{
    Console.WriteLine("Failed to find program path.");
    return;
}
path += "BeyondCompare.exe";
if (File.Exists(path))
{
    Process beyondCompare = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            FileName = path + "BeyondCompare.exe",
            Arguments = string.Empty // You may need to specify args.
        }
    };
    beyondCompare.Start();
}

The source for FindAppPath follows:

static string FindAppPath(string appName)
{
    // If you don't use contracts, check this and throw ArgumentException
    Contract.Requires(!string.IsNullOrEmpty(appName));
    const string keyPath =
        @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

    using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath))
    {
        var installed = 
            (from skName in key.GetSubKeyNames()
            let subkey = key.OpenSubKey(skName)
            select new
            {
                name = subkey.GetValue("DisplayName") as string,
                path = subkey.GetValue("InstallLocation") as string

            }).ToList();

        var desired = installed.FindAll(
            program => program.name != null && 
            program.name.Contains(appName)  &&
            !String.IsNullOrEmpty(program.path));

        return (desired.Count > 0) ? desired[0].path : null;
    }
}

Keep in mind that this method returns the first matching path, so don't feed it an appName argument that's too generic (eg. "Microsoft") or you probably won't get what you're looking for.

Community
  • 1
  • 1
Rob
  • 5,223
  • 5
  • 41
  • 62
1

Well, if you're trying to see if a program exists where you're looking for it (like BeyondCompare.exe), you can just use a call to:

System.IO.File.Exists("path_to_program.exe");

If it returns true, then you know your program exists and you can run it with your process runner code. If it returns false, then you know it's not there and you shouldn't launch your process.

If I'm misunderstanding your question, please let me know and I'll update my answer accordingly.

Thanks. Hope this helps!

David Hoerster
  • 28,421
  • 8
  • 67
  • 102
1

Simple logic to do for this.

string filepath = "c:\windows\test.exe";
bool bOk = false;
try
{
  bOk = System.IO.File.Exists(filepath);
}
catch (Exception ex)
{
      Console.WriteLine(ex.Message);
 }
if (!bOk)
{
    Console.WriteLine("Error: Invalid Path");
}
else
{
   Process p = new Process();
    p.StartInfo.FileName = filepath;
    p.StartInfo.Arguments = "/c dir *.cs";
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();

    string output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();

    Console.WriteLine("Output:");
    Console.WriteLine(output);    
}
apollosoftware.org
  • 12,161
  • 4
  • 48
  • 69
  • 5
    @Rob: I can't speak for the answerer, but my guess is that they left it blank because it's not important to the answer (and specific to the context anyway). It would have been better, of course, to leave a comment indicating that appropriate action should be taken. – siride Sep 17 '11 at 01:03
  • 1
    @siride: Comments would have been just as good, but either way, he edited and I've removed my down-vote. – Rob Sep 17 '11 at 01:07
  • OP doesn't know the path to the executable. File.Exists is not relevant. – Aidan Ryan Sep 17 '11 at 01:18
0

Are you sure you don't need to make that check. Simply start the program without path (only the filename) and set ProcessStartInfo.UseShellExecute = true.

Windows will look for the app in its list of installed app. If it doesn't find it, Process.Start()will fail. The interesting thing is that you never had to care about where the app is stored.

Serge Wautier
  • 21,494
  • 13
  • 69
  • 110