1

VBS は希望どおりに動作しますが、C# を使用する COM API と DTF の両方が InstallLocation を見つけられません。以下は、私がこれまでに行ったことです。


この投稿のおかげで、vbs を使用してレジストリで使用できない InstallLocation を見つけることができました。vbs が で利用可能な COM API を呼び出していることを理解しています %WINDIR%\system32\msi.dll


C# COM API

そこで、C# を使用してこのメ​​ソッドを呼び出すことにしました。しかし、それは失敗しました。存在とインストールは確認できますが、製品 GUID の 1 つを開くことができません (3 回確認しました)。

注: 例外をスローしない製品があり、InstallLocation は適切に検出されました。すべてではありません。

以下は私のコードです。

        static Dictionary<string, string> FindInstallLocationsCOM(Dictionary<string, string> products)
        {
            var locationDictionary = new Dictionary<string, string>();

            // Get the type of the Windows Installer object
            Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");

            // Create the Windows Installer object
            Object installerObj = Activator.CreateInstance(installerType);
            Installer installer = installerObj as Installer;

            foreach (var product in products)
            {
                try
                {
                    var session = installer.OpenProduct(product.Value);
                    if (session != null)
                    {
                        session.DoAction("CostInitialize");
                        session.DoAction("CostFinalize");
                        var installLocation = session.Property["INSTALLLOCATION"];
                        MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Install Location : " + installLocation);
                        locationDictionary.Add(product.Key, installLocation);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error : Could not open Product " + e.Message + "\n" + "Product : " + product.Key + "\n" + "Product Code : " + product.Value);
                }
            }

            return locationDictionary;
        }

うまくいきませんでした。DTF を試してみましょう。


C# DTF

しかし、それもうまくいきませんでした。以下は私のコードです。これは例外をトリガーせず、COM API 経由で検出できなかったものでさえ、それ自体を検出できましたが、InstallLocation プロパティは空の文字列でした。

注: InstallLocation プロパティが入力されている製品がありました。すべてではありません。

        static Dictionary<string,string> FindInstallLocation(Dictionary<string,string> products)
        {
            var locationDictionary = new Dictionary<string, string>();

            foreach (var product in products)
            {
                try
                {
                    var installed = new ProductInstallation(product.Value);
                    if (installed != null)
                    {
                        var installLocation = installed.InstallLocation;
                        MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Install Location : " + installLocation);
                        locationDictionary.Add(product.Key, installLocation);
                    }
                    else
                    {
                        MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Is not installed");
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error :  " + e.Message + "\n" + "Product : " + product.Key + "\n" + "Product Code : " + product.Value);
                }
            }

            return locationDictionary;
        }

C# のどちらも検出できないのに、VBS が InstallLocation を検出できるのはなぜですか? 私は何が欠けていますか?

VBS が使えないのは、vb.net を使わないと try catch が使えないからです。

4

2 に答える 2