我的要求是阅读与Adobe Acrobat reader相关的特定注册表项,并根据该项的值做出决定。
虽然这看起来很简单,但我需要使用Registry类查询密钥(对于.NET) 然后根据价值做出决定。
然而,我现在面临的问题是,几乎每个新版本的Adobe Acrobat Reader中的注册表键位置都在不断变化。
我现在能想到的就是在我的代码中设置一个用于处理所有不同Adobe版本的开关盒。
RegistryKey adobe = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe");
if (adobe != null)
{
RegistryKey acroRead = adobe.OpenSubKey("Acrobat Reader");
if (acroRead != null)
{
string[] acroReadVersions = acroRead.GetSubKeyNames();
Console.WriteLine("The following version(s) of Acrobat Reader are installed: ");
foreach (string versionNumber in acroReadVersions)
{
switch(versionNumber)
{
case 1.x = //do something;
//break;
case 2.x = //do something;
//break;
case 6.x = //do something;
//break;
case 9.x = //do something;
//break;
}
}
}
}
但有些人对此方法不满意。每次Adobe发布新版本时,我都必须确保我必须以不同的方式处理它。任何有关更好方法的建议。
谢谢
答案 0 :(得分:2)
你最希望打开包含版本号的注册表项,然后枚举每个子键,可能验证它看起来像版本号,然后在每个子键中查找你想要的东西。您可能只想使用找到的最高版本。
显然,只有当你想要的东西总是包含在相对于版本密钥的相同注册表项中,或者总是在同一个命名条目中时,这才会起作用(然后你必须枚举子键下的每个元素来寻找你想要的东西)。
如果您想要的东西在每个版本中更改名称和位置,那么您将遇到问题,除非您可以从数据中以某种方式识别它,在这种情况下枚举每个元素并查看4数据并尝试确定它是否是你想要什么,但这种方法很可能充满危险或误报。
答案 1 :(得分:0)
嗯,我有完全相同的问题,因为我知道Adobe的决策和材料并不是那么出色,我想我会尝试这种方法:
public static string AcrobatReaderPath
{
get
{
var paths = new List<string>()
{
Registry.GetValue(@"HKEY_CLASSES_ROOT\Software\Adobe\Acrobat\Exe", "", @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe") as string
};
var files = Directory.GetFileSystemEntries(@"C:\Program Files (x86)\Adobe\", @"*Acr*R*d*32.exe", SearchOption.AllDirectories);
paths.AddRange(files);
foreach(var path in paths) if (File.Exists(path)) return path;
return "";
}
}
我的注册表与Acrobat没有任何关系:
HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\
..所以看来Adobe正在整个注册表中移动他们的注册表项,时间过去了...... 我希望他们将来避免将Acrobat本身移到Program Files文件夹之外......(你永远不会跟这些人有所了解......)
答案 2 :(得分:0)
我认为您可以应用以下逻辑: adobe文件关联保存在注册表中 - 您可以在下面阅读它们 HKEY_CLASSES_ROOT \ .pdf \ OpenWithList
这些子项是应用程序名称(如果有):
使用它们来组合和读取键(打开或读取应该存在)
如果存在,它们将类似于 “C:\ Program Files(x86)\ Adobe \ Acrobat 7.0 \ Acrobat \ Acrobat.exe”“%1” 从那里你可以剥离%1并获得adobe应用程序路径。
这是C#代码:
private void AddShellCommandDefault(List<string> lst, RegistryKey shell, string reg KeyOpenRead) { var shellOpen = shell.OpenSubKey(regKeyOpenRead); if (shellOpen == null) return; var shellOpenCommand = shellOpen.OpenSubKey("command"); if (shellOpenCommand == null) return; var defaultVal = shellOpenCommand.GetValue(null); if (defaultVal == null) return; int kex = defaultVal.ToString().LastIndexOf(".exe", StringComparison.OrdinalIgnoreCase); if (kex < 0) return; lst.Add(defaultVal.ToString().Substring(0, kex).Replace("\"", "") + ".exe"); } public List<string> GetAdobeApps() { var addobeList = new List<string>(); // HKEY_CLASSES_ROOT\.pdf\OpenWithList\Acrobat.exe // HKEY_CLASSES_ROOT\Applications\Acrobat.exe\shell\Open\command // default "C:\Program Files (x86)\Adobe\Acrobat 7.0\Acrobat\Acrobat.exe" "%1" var adobe = Registry.ClassesRoot.OpenSubKey(".pdf"); if (adobe == null) return addobeList; var openWith = adobe.OpenSubKey("OpenWithList"); if (openWith == null) return addobeList; var apps = Registry.ClassesRoot.OpenSubKey("Applications"); if (apps == null) return addobeList; foreach (string sLong in openWith.GetSubKeyNames()) { string s = sLong.Split(@"\/".ToCharArray()).Last(); var adobeApp = apps.OpenSubKey(s); if (adobeApp == null) continue; var shell = adobeApp.OpenSubKey("shell"); if (shell == null) continue; AddShellCommandDefault(addobeList, shell, "Read"); AddShellCommandDefault(addobeList, shell, "Open"); } return addobeList; }
When run GetAdobeApps, it returns collection similar to Count = 2 [0]: "C:\\Program Files (x86)\\Adobe\\Acrobat 7.0\\Acrobat\\Acrobat.exe" [1]: "C:\\Program Files (x86)\\Adobe\\Reader 9.0\\Reader\\AcroRd32.exe"