C# wpf - searching through registry for installed programs does not return office softwrae

Kalpana 286 Reputation points
2021-01-15T02:54:29.847+00:00

Hi,

I am iterating through 3 registries, however I am not able to find the office software installed on my machine.
What am I missing, please advice ?

     private void LoadPrograms(object sender, RoutedEventArgs e)
        {

            RegistryKey[] arrayofrks = new RegistryKey[3];
            arrayofrks[0] = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            arrayofrks[1] = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            arrayofrks[2] = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");

            //arrayofrks[3] = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
           //arrayofrks[4] = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);



            Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            string dispname;
            string ipath;


            for(int i=0; i < arrayofrks.Length; i++)
            {
                using (RegistryKey rk = arrayofrks[i])
                {
                    foreach (string skName in rk.GetSubKeyNames())
                    {
                        using (RegistryKey sk = rk.OpenSubKey(skName))
                        {
                            try
                            {

                                if (!(sk.GetValue("DisplayName") == null))
                                {
                                    dispname = sk.GetValue("DisplayName").ToString();
                                    if (sk.GetValue("InstallLocation") == null || sk.GetValue("InstallLocation").ToString() == "")
                                    {
                                        ipath = "Path not known";
                                    }
                                    else
                                    {
                                        ipath = sk.GetValue("InstallLocation").ToString();


                                    }

                                    listofprogs.Add(new InstalledProgram()
                                    {
                                        DisplayName = dispname,
                                        Path = ipath
                                    });

                                }

                            }

                            catch (Exception ex)
                            {

                            }

                        }
                    }


                    //                //if(dispname !=null)
                    //                //{
                    //                //    listofprogs.Add(new InstalledProgram()
                    //                //    {
                    //                //        DisplayName = dispname,
                    //                //        Path = ipath
                    //                //    });
                    //                //}




                    //                //ListViewItem item;
                    //                //if (displayName != null)
                    //                //{
                    //                //    if (size != null)
                    //                //        item = new ListViewItem(new string[] {displayName.ToString(),                size.ToString()});
                    //                //    else
                    //                //        item = new ListViewItem(new string[] { displayName.ToString() });
                    //                //    lstDisplayHardware.Items.Add(item);
                    //                //}

                    //            }

                    //            catch (Exception ex)
                    //            {


                    //            }

                    //        }

                    //    }



                    //}











                }
            }



            lvprograms.ItemsSource = listofprogs;
            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvprograms.ItemsSource);
            view.Filter = UserFilter;


        }
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,686 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,364 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 82,031 Reputation points
    2021-01-16T08:38:40.71+00:00

    One of the ways is with AssocQueryString and a ProgId from Office

    For example, with Winword =>

    string sProgId = "Word.Document";  
    int nLength = 260;  
    var sbAssociatedExe = new StringBuilder(nLength);  
    HRESULT hr = AssocQueryString(ASSOCF.ASSOCF_NONE, ASSOCSTR.ASSOCSTR_EXECUTABLE, sProgId, null, sbAssociatedExe, ref nLength);  
    if (hr == 0)  
    {  
        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(sbAssociatedExe.ToString());  
        MessageBox.Show(string.Format("Winword = {0} {1}", fvi.FileDescription, fvi.FileVersion));  
    }  
    

    Declarations :

    public enum HRESULT : int  
    {  
        S_OK = 0,  
        S_FALSE = 1,  
        E_NOINTERFACE = unchecked((int)0x80004002),  
        E_NOTIMPL = unchecked((int)0x80004001),  
        E_FAIL = unchecked((int)0x80004005)  
    }  
      
    [Flags]  
    public enum ASSOCF : uint  
    {  
        ASSOCF_NONE = 0x00000000,  
        ASSOCF_INIT_NOREMAPCLSID = 0x00000001,  //  do not remap clsids to progids  
        ASSOCF_INIT_BYEXENAME = 0x00000002,  //  executable is being passed in  
        ASSOCF_OPEN_BYEXENAME = 0x00000002,  //  executable is being passed in  
        ASSOCF_INIT_DEFAULTTOSTAR = 0x00000004,  //  treat "*" as the BaseClass  
        ASSOCF_INIT_DEFAULTTOFOLDER = 0x00000008,  //  treat "Folder" as the BaseClass  
        ASSOCF_NOUSERSETTINGS = 0x00000010,  //  dont use HKCU  
        ASSOCF_NOTRUNCATE = 0x00000020,  //  dont truncate the return string  
        ASSOCF_VERIFY = 0x00000040,  //  verify data is accurate (DISK HITS)  
        ASSOCF_REMAPRUNDLL = 0x00000080,  //  actually gets info about rundlls target if applicable  
        ASSOCF_NOFIXUPS = 0x00000100,  //  attempt to fix errors if found  
        ASSOCF_IGNOREBASECLASS = 0x00000200,  //  dont recurse into the baseclass  
        ASSOCF_INIT_IGNOREUNKNOWN = 0x00000400,  //  dont use the "Unknown" progid, instead fail  
        ASSOCF_INIT_FIXED_PROGID           = 0x00000800,  //  the Init() pszAssoc value is a ProgId that should not be mapped using the current user defaults  
        ASSOCF_IS_PROTOCOL                 = 0x00001000,  //  the Init() pszAssoc value is an uri scheme (not including the ":") that should be mapped using the current user defaults  
        ASSOCF_INIT_FOR_FILE               = 0x00002000,  //  use this flag when specifying ASSOCF_INIT_FIXED_PROGID if the ProgId corresponds with a file extension based association  
        ASSOCF_IS_FULL_URI                 = 0x00004000,  //  Used to specify that full http/https URI is being passed for target resolution  
        //  Only one of ASSOCF_INIT_FIXED_PROGID, ASSOCF_IS_PROTOCOL or ASSOCF_IS_FULL_URI can be specified at a time.  
        ASSOCF_PER_MACHINE_ONLY            = 0x00008000,  //  Enforces per-machine association look-up only and avoid HKCU.  
        // For http/https uri associations, this enables selecting the OS default browser, that is a controlled by  
        // policy settings, instead of the default browser.  
        ASSOCF_APP_TO_APP                  = 0x00010000,  
    }  
      
    public enum ASSOCSTR  
    {  
        ASSOCSTR_COMMAND = 1,  //  shell\verb\command string  
        ASSOCSTR_EXECUTABLE,        //  the executable part of command string  
        ASSOCSTR_FRIENDLYDOCNAME,   //  friendly name of the document type  
        ASSOCSTR_FRIENDLYAPPNAME,   //  friendly name of executable  
        ASSOCSTR_NOOPEN,            //  noopen value  
        ASSOCSTR_SHELLNEWVALUE,     //  query values under the shellnew key  
        ASSOCSTR_DDECOMMAND,        //  template for DDE commands  
        ASSOCSTR_DDEIFEXEC,         //  DDECOMMAND to use if just create a process  
        ASSOCSTR_DDEAPPLICATION,    //  Application name in DDE broadcast  
        ASSOCSTR_DDETOPIC,          //  Topic Name in DDE broadcast  
        ASSOCSTR_INFOTIP,           //  info tip for an item, or list of properties to create info tip from  
        ASSOCSTR_QUICKTIP,          //  same as ASSOCSTR_INFOTIP, except, this list contains only quickly retrievable properties  
        ASSOCSTR_TILEINFO,          //  similar to ASSOCSTR_INFOTIP - lists important properties for tileview  
        ASSOCSTR_CONTENTTYPE,       //  MIME Content type  
        ASSOCSTR_DEFAULTICON,       //  Default icon source  
        ASSOCSTR_SHELLEXTENSION,    //  Guid string pointing to the Shellex\Shellextensionhandler value.  
        ASSOCSTR_DROPTARGET,        //  The CLSID of DropTarget  
        ASSOCSTR_DELEGATEEXECUTE,   //  The CLSID of DelegateExecute  
                                    // a string value of the uri protocol schemes, for example "http:https:ftp:file:" or "*" indicating all  
        ASSOCSTR_SUPPORTED_URI_PROTOCOLS,  
        ASSOCSTR_PROGID,            // The ProgId provided by the app associated with the file type or uri scheme based on user default settings.  
        ASSOCSTR_APPID,             // The AppUserModelID of the app associated with the file type or uri scheme based on user default settings.  
        ASSOCSTR_APPPUBLISHER,      // THe publisher of the app associated with the file type or uri scheme based on user default settings.  
        ASSOCSTR_APPICONREFERENCE,  // The icon reference of the app associated with the file type or uri scheme based on user default settings.  
        ASSOCSTR_MAX                //  last item in enum...  
    }  
      
    [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]  
    public static extern HRESULT AssocQueryString(ASSOCF flags, ASSOCSTR str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref int pcchOut);  
    
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Timon Yang-MSFT 9,576 Reputation points
    2021-01-15T08:19:33.07+00:00

    I suggest you use MSI API to get the list of installed applications, we can use this way to get a more complete list including office software.

            [DllImport("msi.dll", CharSet = CharSet.Unicode)]  
            static extern Int32 MsiGetProductInfo(string product, string property,  
           [Out] StringBuilder valueBuf, ref Int32 len);  
      
            [DllImport("msi.dll", SetLastError = true)]  
            static extern int MsiEnumProducts(int iProductIndex,  
                StringBuilder lpProductBuf);  
      
            static void Main(string[] args)  
            {  
                StringBuilder sbProductCode = new StringBuilder(39);  
                int iIdx = 0;  
                while (  
                    0 == MsiEnumProducts(iIdx++, sbProductCode))  
                {  
                    Int32 productNameLen = 512;  
                    StringBuilder sbProductName = new StringBuilder(productNameLen);  
      
                    MsiGetProductInfo(sbProductCode.ToString(),  
                        "ProductName", sbProductName, ref productNameLen);  
                      
                    Int32 installDateLen = 124;  
                    StringBuilder installDate = new StringBuilder(installDateLen);  
      
                    MsiGetProductInfo(sbProductCode.ToString(),  
                        "InstallDate", installDate, ref installDateLen);  
      
                    Console.WriteLine("ProductName {0}: {1}",  
                        sbProductName,  installDate);  
                }  
            }  
    

    57017-microsoftteams-image.png
    I got two properties, product name and install date in the example, you can get more if you need, please refer to this document:
    MsiGetProductInfoA function (msi.h)

    Update:
    Maybe you can try WMI, I used this method and got a list of software including Office related.

                ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");  
                foreach (ManagementObject mo in mos.Get())  
                {  
                    Console.WriteLine(mo["Name"]);  
                }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Ken Tucker 5,846 Reputation points
    2021-01-18T11:27:14.287+00:00

    Try using the wmi add a reference to System.Managment

            var query = new ManagementObjectSearcher("Select * from Win32_Product");
            foreach (var item in query.Get())
            {
                Console.WriteLine(item["Name"]);
            }
    
    0 comments No comments