2

I would like to obtain a list, using C#, of all progis's on my computer. I know I can scan the registry, something like this:

var regClis = Registry.ClassesRoot.OpenSubKey("CLSID");
var progs = new List<string>();

foreach (var clsid in regClis.GetSubKeyNames()) {
    var regClsidKey = regClis.OpenSubKey(clsid);
    var ProgID = regClsidKey.OpenSubKey("ProgID");
    var regPath = regClsidKey.OpenSubKey("InprocServer32");

    if (regPath == null)
        regPath = regClsidKey.OpenSubKey("LocalServer32");

    if (regPath != null && ProgID != null) {
        var pid = ProgID.GetValue("");
        var filePath = regPath.GetValue("");
        progs.Add(pid + " -> " + filePath);
        regPath.Close();
    }

    regClsidKey.Close();
}

The code is from this blog.

Does anyone know if there's a simpler way? Also, as far as I understand how this works, the code above would probaly only give me in-process com. What if I need out of process progids as well?

Thanks in advance

Farawin
  • 1,375
  • 2
  • 14
  • 19
  • 1
    `LocalServer32` is for out-of-process. It cannot be simpler than direct enumeration. – Roman R. Oct 04 '12 at 09:13
  • If you do scan the registry with code like this, remember that `RegistryKey` is `IDisposable` - you should `Dispose` every object returned from a call to `OpenSubKey`, otherwise you'll consume a great many registry handles until garbage collection when the finalizer thread gets round to closing them. – Chris Dickson Oct 05 '12 at 10:44

2 Answers2

3

It is too simple. Listing the ProgId in the CLSID key is an option, it isn't required. Examples of ProgIDs on my machine that don't have it are Briefcase, CABFolder, FaxCommon.1, JobObject, NetworkConnections, Shell.AutoPlay etcetera.

You have to start with iterating the root and look for keys that have a subkey named CLSID. Which gives you the clsid guid. Then open HKCR\CLSID\{guid} and look for the path.

You also have to watch out for ProgIDs that are only registered for the current user. Do so by first iterating HKCU\Software\Classes and filtering any duplicates you find from iterating HKCR.

Beware that this is all fairly risky, there's plenty of junk you'll run into from poorly designed COM component registrations. Use try/catch to catch the junk.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

This will give you all registered ProgIDs, local or remote (as out-of-proc, not another machine, of course). Besides, the code is just enumerating the registry key, it is simple already.

If the question is 'is there a specific API for this', there is not one provided by MS. Quite possibly there is some third-party implementation which basically does the same thing as this code.

Zdeslav Vojkovic
  • 14,391
  • 32
  • 45