首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#:如何使安装程序与控制面板程序和功能完全相同?

C#:如何使安装程序与控制面板程序和功能完全相同?
EN

Stack Overflow用户
提问于 2013-03-20 12:55:53
回答 3查看 19.1K关注 0票数 18

我读了很多关于获取程序的信息。所有算法都没有做我想做的事。我需要安装与控制面板完全一样的程序。

所以我用:

  1. WMI Win32_Product类。它只显示已安装的msi程序。
  2. 注册表项。HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall。同样,某些程序没有显示在控制面板中,有些程序显示在控制面板中,而不是在此注册表节点中。

那么,世界上有谁知道哪种算法使用控制面板来显示已安装的程序呢?

UPD1 1:是的,我使用64位,我知道64位安装程序"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall“还有另一个节点,但是下面的代码列举了twise HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall部分,奇怪的是.

var registry_key =新列表();string registry_key=registry_key使用(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { name (RegistryKey subkey =key.OpenSubKey(Subkey_name){ var名称= (string)subkey.GetValue("DisplayName");如果(!string.IsNullOrEmpty(名称)){programs.Add(名称);} registry_key =programs.Add使用(Microsoft.Win32.RegistryKey键= Registry.LocalMachine.OpenSubKey(registry_key)) { foreach (key.GetSubKeyNames()中的字符串subkey_name ){ var (RegistryKey subkey =key.OpenSubKey(Subkey_name){var name = (string)subkey.GetValue("DisplayName");if (!string.IsNullOrEmpty(名称)){programs.Add(名称);} foreach ( programs.OrderBy(x => x)中的var程序){Console.WriteLine(程序);}

EN

回答 3

Stack Overflow用户

发布于 2015-10-22 05:40:00

MelnikovI的答案在大多数情况下都足够了--我的列表中有144项,而程序和特性中有143项。用于审查,他的解决方案是访问以下注册表位置:

  • HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

要符合条件,每个子项必须具有:

  • DisplayName REG_SZ值

也不得拥有:

  • SystemComponent REG_DWORD (非零)
  • ParentKeyName或ParentDisplayName REG_SZ值
  • ReleaseType REG_SZ值

我发现的one增强是用于Windows条目,定义为:

  • 键名是一个标准的GUID字符串。
  • WindowsInstaller REG_DWORD存在(且非零)

对于这些条目,您可以采取其他步骤,从MsiGetProductInfoW msi.dll中使用Win32函数,并为键表示的GUID请求"VersionString“属性。

如果此函数返回1605: ERROR_UNKNOWN_PRODUCT,则意味着该条目不是根据Windows安装的,应该从显示中排除。

在实现这个小调整之后,我的列表现在与程序和功能相同。

票数 4
EN

Stack Overflow用户

发布于 2015-09-14 21:48:18

我使用了MelnikovI编写的代码(这非常有用),并添加了一些内容。首先,它搜索注册表中的四个位置:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

HKCU\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

它还检查是否有子项--如果没有,则跳过该子项。

最后,它只允许某一组字符^a-zA-Z0-9 .()+-。

我只是从C#开始,所以我不知道如何遍历所有四个区域,所以我有两个循环(一个用于HKLM,一个用于HKCU)。

代码语言:javascript
运行
复制
public static class InstalledPrograms
    {
      public static List<string> GetInstalledPrograms()
        {
            var result = new List<string>();
            result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32));
            result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64));
            result.Sort();
            return result;
        }
        private static string cleanText(string dirtyText)
        {
            Regex rgx = new Regex("[^a-zA-Z0-9 .()+-]");
            string result = rgx.Replace(dirtyText, "");
            return result;
        }
        private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView)
        {
            var result = new List<string>();
            List<string> uninstall = new List<string>();
            uninstall.Add(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            uninstall.Add(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
            foreach (string registry_key in uninstall)
            {
               using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key))
               {
                    foreach (string subkey_name in key.GetSubKeyNames())
                    {
                        using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                        {
                            if (IsProgramVisible(subkey))
                            {
                                result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString());
                            }
                        }
                    }
                }
                using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, registryView).OpenSubKey(registry_key))
                {
                    if (key != null)
                    {
                        foreach (string subkey_name in key.GetSubKeyNames())
                        {
                            using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                            {
                                if (IsProgramVisible(subkey))
                                {
                                    result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString());
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }

如果有人感兴趣,我会将结果与我一直使用的PowerShell进行比较,结果是相同的。

代码语言:javascript
运行
复制
##Get list of Add/Remove programs
if (!([Diagnostics.Process]::GetCurrentProcess().Path -match '\\syswow64\\'))
{
$uninstallPath = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$uninstallWow6432Path = "\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
@(
if (Test-Path "HKLM:$uninstallWow6432Path" ) { Get-ChildItem "HKLM:$uninstallWow6432Path"}
if (Test-Path "HKLM:$uninstallPath" ) { Get-ChildItem "HKLM:$uninstallPath" }
if (Test-Path "HKCU:$uninstallWow6432Path") { Get-ChildItem "HKCU:$uninstallWow6432Path"}
if (Test-Path "HKCU:$uninstallPath" ) { Get-ChildItem "HKCU:$uninstallPath" }
) |
ForEach-Object { Get-ItemProperty $_.PSPath } |
Where-Object {
$_.DisplayName -and !$_.SystemComponent -and !$_.ReleaseType -and !$_.ParentKeyName -and ($_.UninstallString -or $_.NoRemove)
} |
Sort-Object DisplayName |
Select-Object DisplayName
}
else
{
"You are running 32-bit Powershell on 64-bit system. Please run 64-bit Powershell instead." | Write-Host -ForegroundColor Red
}
票数 2
EN

Stack Overflow用户

发布于 2019-04-18 16:36:12

其他几个答案中讨论的SystemComponent注册表项通常是一个可能值为0或1的REG_DWORD。然而,我看到了一些实例(比如Microsoft 2010和Microsoft 2010),其中SystemComponent是一个没有数据的REG_SZ。因此,任何将SystemComponent转换为int的解决方案都可能在这些情况下引发异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15524161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档