为什么 vbs 能够找到 INSTALLLOCATION,而使用 DTF 和 MSI API 的 C# 却找不到?

2023-12-02

VBS 按我的预期工作,但是使用 C# 的 COM API 和 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的原因是因为除非我使用vb.net,否则try catch不可用。


在 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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 vbs 能够找到 INSTALLLOCATION,而使用 DTF 和 MSI API 的 C# 却找不到? 的相关文章

  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • 使用参数将变量从 vbscript 传递到批处理文件

    请问如何将 inp 变量从这段 vb 传递到我的名为 job bat 的批处理 确实 在从 job bat 进行回显 echo 2 时 我注意到 inp 未正确传递 提示命令视图 inp而不是从 vbs 检索到的值 谢谢 For Each
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif

随机推荐