我有一个C#程序,我必须获取安装的msi的产品代码。我只有msi名称作为输入。这可以通过编程来完成吗?获取产品安装的Msi代码
回答
这是我曾经得到任何MSI的UninstallString
的代码。
private string GetUninstallString(string msiName)
{
Utility.WriteLog("Entered GetUninstallString(msiName) - Parameters: msiName = " + msiName);
string uninstallString = string.Empty;
try
{
string path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products";
RegistryKey key = Registry.LocalMachine.OpenSubKey(path);
foreach (string tempKeyName in key.GetSubKeyNames())
{
RegistryKey tempKey = key.OpenSubKey(tempKeyName + "\\InstallProperties");
if (tempKey != null)
{
if (string.Equals(Convert.ToString(tempKey.GetValue("DisplayName")), msiName, StringComparison.CurrentCultureIgnoreCase))
{
uninstallString = Convert.ToString(tempKey.GetValue("UninstallString"));
uninstallString = uninstallString.Replace("/I", "/X");
uninstallString = uninstallString.Replace("MsiExec.exe", "").Trim();
uninstallString += " /quiet /qn";
break;
}
}
}
return uninstallString;
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}
这会给这样的结果:
MsiExec.exe /I{6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE}
从这个字符串,你可以把括号{},这将是6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE
内子。我希望这可能是产品代码。
如果您在64位计算机上使用此代码并且您的应用程序是32位,这将失败,因为它会将您重定向到软件中的“Wow6432Node”。改为使用'RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,RegistryView.Registry64).OpenSubKey(path)'。 – modiX 2016-08-04 09:07:17
对this question有帮助吗?他们想要获得产品名称,但也可能适用于产品代码?
编辑
如果没有MSI文件本身来访问数据库(通过上面的链接到的其他问题的建议),您可以尝试搜索以下注册表路径为您的MSI的名字文件:
HKEY_CLASSES_ROOT\Installer\Products\*\SourceList
Products
分支下有很多条目。他们每个人都是产品的关键。每个分支应包含SourceList
节点,该节点又应包含值PackageName
。该值包含MSI文件的名称。
所以我会做的是:
for each key in Products
{
open SourceList subkey
read PackageName value
if name equals my msi file name
{
return key-name formatted as GUID
}
}
好的:-1因为...? – 2011-06-14 14:46:51
但是,密钥名称实际上是产品代码的混乱版本。请参阅此处以获取从ProductCode到注册表项格式的帮助(http://stackoverflow.com/questions/1881643/msi-product-code-from-product-id/1881818#1881818)。你只需要反转即可解密密钥名称。 – 2014-07-05 15:17:47
该代码直接从MSI文件获取产品代码。所以这允许在不安装文件的情况下阅读代码。
class MsiHandle : SafeHandleMinusOneIsInvalid
{
public MsiHandle()
: base(true)
{ }
protected override bool ReleaseHandle()
{
return NativeMethods.MsiCloseHandle(handle) == 0;
}
}
class NativeMethods
{
const string MsiDll = "Msi.dll";
[DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)]
public extern static uint MsiOpenPackageW(string szPackagePath, out MsiHandle product);
[DllImport(MsiDll, ExactSpelling=true)]
public extern static uint MsiCloseHandle(IntPtr hAny);
[DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)]
static extern uint MsiGetProductPropertyW(MsiHandle hProduct, string szProperty, StringBuilder value, ref int length);
[DllImport(MsiDll, ExactSpelling = true)]
public static extern int MsiSetInternalUI(int value, IntPtr hwnd);
public static uint MsiGetProductProperty(MsiHandle hProduct, string szProperty, out string value)
{
StringBuilder sb = new StringBuilder(1024);
int length = sb.Capacity;
uint err;
value = null;
if(0 == (err = MsiGetProductPropertyW(hProduct, szProperty, sb, ref length)))
{
sb.Length = length;
value = sb.ToString();
return 0;
}
return err;
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static int Main(string[] args)
{
string msiFile = args[0];
NativeMethods.MsiSetInternalUI(2, IntPtr.Zero); // Hide all UI. Without this you get a MSI dialog
MsiHandle msi;
uint err;
if (0 != (err = NativeMethods.MsiOpenPackageW(args[0], out msi)))
{
Console.Error.WriteLine("Can't open MSI, error {0}", err);
return 1;
}
// Strings available in all MSIs
string productCode;
using (msi)
{
if (0 != NativeMethods.MsiGetProductProperty(msi, "ProductCode", out productCode))
throw new InvalidOperationException("Can't obtain product code");
Console.WriteLine(productCode);
return 0;
}
}
}
在颠覆
全部例如在http://ankhsvn.open.collab.net/svn/ankhsvn/trunk/src/tools/Ankh.Chocolatey/ 使用用户名 '客户',没有密码。
有最快捷最简单的方法 - 使用带有条件查询字符串的WMI。
public string GetProductCode(string productName)
{
string query = string.Format("select * from Win32_Product where Name='{0}'", productName);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (ManagementObject product in searcher.Get())
return product["IdentifyingNumber"].ToString();
}
return null;
}
这个程序不错,它消耗了很多时间 – 2015-10-08 04:00:58
private static bool GetUninstallString(string ProductName)
{
try
{
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
var key = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") ??
localKey.OpenSubKey(
@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
if (key == null)
return false;
return key.GetSubKeyNames()
.Select(keyName => key.OpenSubKey(keyName))
.Select(subkey => subkey.GetValue("DisplayName") as string)
.Any(displayName => displayName != null && displayName.Contains(ProductName));
}
catch
{
// Log message
return false;
}
}
这是搜索字符串由产品名称
- 1. 来自产品ID的MSI产品代码?
- 2. 虽然产品代码不同,但MSIEXEC未能安装“已安装此产品的较新版本”产品
- 3. 获取产品代码Opencart的
- 4. 以编程方式获取Visual Studio安装项目的应用产品代码
- 5. msi安装程序 - 此产品的另一个版本已安装
- 6. 安装期间运行sql代码的msi安装程序
- 7. MSI安装应该等待产品运行
- 8. MSI安装程序没有正确卸载产品
- 9. 如何查询InstallShield安装程序exe以获取产品代码而不安装它?
- 10. 具有相同产品代码的不同msi -s
- 11. 如何获取已安装软件产品的列表?
- 12. 卸载与产品代码失败“安装源不可用”
- 13. 如何以编程方式获取MSI产品版本的C#
- 14. NSIS已安装产品
- 15. 按照产品类别在WooCommerce的简码中获取产品
- 16. 产品代码流
- 17. MSI安装包
- 18. MSI:在安装
- 19. 从命令行获取msi产品名称,版本
- 20. 创新安装中的msi返回码
- 21. 获取价值的产品代码字段
- 22. 如何在修改已安装的产品时防止msi错误2335?
- 23. 如何防止一组具有通用升级代码的MSI安装我的msi后安装?
- 24. msi在Windows Server 2003 R2中的安装错误代码1603
- 25. 从安装程序类中获取当前msi安装文件的名称
- 26. WiX的复制版本产品安装
- 27. 使用ASIN代码从amazon.com获取产品信息
- 28. 获取未知属性:前端\ modules \ printinvoice \ models \ Prodfin ::产品代码
- 29. Android zxing:扫描UPC_A代码时如何获取产品名称
- 30. MSI安装工具
你使用注册表编辑器来搜索注册表的机器上安装的软件非常有用? – 2011-06-14 14:46:05
有关完整源代码的最终解决方案吗? – Kiquenet 2012-07-27 06:40:21
** [DTF(部署工具基础)](https://serverfault.com/questions/577969/is-it-possible-to-disable-msiexec-help-gui/596519#596519)**是一堆随WiX下载提供的.NET类将为您提供一种访问和修改MSI文件的简单方法,而无需任何COM互操作或阻塞。有关更多上下文,请参阅提供的链接中的信息。 ** [下载WiX](http://wixtoolset.org/)**以获取DTF组件。 – 2017-07-31 00:22:15