簡體   English   中英

為什么 vbs 能夠找到 INSTALLLOCATION 而 C# 同時使用 DTF 和 MSI API 不能?

[英]Why is vbs able to find the INSTALLLOCATION when C# using both DTF and MSI API cannot?

VBS 按我的要求工作,但 COM API 和使用 C# 的 DTF 都沒有找到 InstallLocation。 以下是我到目前為止所做的。


感謝這篇文章,我能夠使用 vbs 找到在注冊表中不可用的 InstallLocation。 我知道 vbs 正在調用 COM API 在%WINDIR%\system32\msi.dll上可用。


C# COM API

所以我想我會使用C#來調用這個方法。 但它失敗了。 即使我可以確認存在和安裝,它也無法打開其中一個產品 GUID(我檢查了三次)。

注意:有些產品沒有拋出異常並且正確找到了 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;
        }

為什么 VBS 能夠檢測到 InstallLocation 而 C# 都檢測不到? 我錯過了什么?

我不能使用 VBS 的原因是因為 try catch 不可用,除非我使用 vb.net。

在 SteinAsmul 建議 DTF 不會自動調用與成本相關的操作之后,我進一步閱讀了 DTF 文檔。

我發現DoAction在 DTF 中也可用。 所以我使用了以下內容,var installLocation 現在有了我正在尋找的預期值。

Installer.SetInternalUI(InstallUIOptions.Silent);
var session = Installer.OpenProduct(product.Value);
session.DoAction("CostInitialize");
session.DoAction("CostFinalize");
var installLocation = session["INSTALLLOCATION"];
session.Close();

盡管它不是很“完善”或經過測試,但您可以嘗試一下。

使用 COM:

using System;
using System.Windows.Forms;
using WindowsInstaller;

namespace DTFTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            var installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
            if (installer == null) { return; }

            var session = installer.OpenProduct("Product-GUID-here");
            if (session == null) { return; }

            session.DoAction("CostInitialize");
            session.DoAction("CostFinalize");

            MessageBox.Show(session.Property["Directory-Property-Here"]);
        }
    }
}

使用 DTF:

using System;
using Microsoft.Deployment.WindowsInstaller;
using System.Windows.Forms;

namespace DTFTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Installer.SetInternalUI(InstallUIOptions.Silent);
            var session = Installer.OpenProduct("Product-GUID-here");
            session.DoAction("CostInitialize");
            session.DoAction("CostFinalize");
            MessageBox.Show(session["Directory-Property-Here"]);
            session.Close();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM