【发布时间】:2012-01-22 02:40:02
【问题描述】:
好的,我会尽力而为,但我认为我的英语在涉及复杂的主题/短语时仍然太糟糕了。
我必须构建一个类(目前它不是静态的)来检索有关外部应用程序(客户 PC 上可用的软件)的信息。
Linux 类很容易编写代码,但现在我必须在 Windows 上实现它。
基本上,我在从我的应用程序的 x86 版本读取 x64 注册表时遇到了一些困难:您只能通过使用 [DllImport("advapi32.dll")] 来做到这一点。
从一开始我就知道软件退役很大程度上取决于目标操作系统,所以我创建了 4 个类:
public abstract ExternalApplications 定义了一些基本方法,由ExternalApplicationsWin、ExternalApplicationsMac 和ExternalApplicationsUnix 派生而来。
在我的应用程序中,我创建了一个 ExternalApplications 实例并通过切换操作系统类型来分配它:
ExternalApplications ex = null;
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32NT:
goto default;
case PlatformID.MacOSX:
_ex = new ExternalApplicationsMac(); break;
case PlatformID.Unix:
_ex = new ExternalApplicationsUnix(); break;
default:
_ex = new ExternalApplicationsWin(); break;
}
这样,方法调用将自动分派到正确的 ExternalApplicationsXXX 类型。
现在通过介绍[DllImport("advapi32.dll")],我有义务:
- 更改类结构(为静态外部)
- 它可能会在 Unix/Mac OS X 编译(使用 DllNotFoundException)
有几种选择: (1) 我可以为 Linux、Mac 和 Windows 创建 3 个具有相同目标程序集名称的并行项目 (.cproj)。这些项目将包含相同的类和方法,因此我可以在我的应用程序中毫无问题地引用它。
这个选项很糟糕,它缺乏自动化:一切都是手动完成的。
(2) 我可以使用 C# 指令来完成预防性的“DllImport”代码排除
#if !MONO
...
#endif
我确信还有许多其他方法,例如 DLLMAP 和其他方法。 我认为更有经验的程序员会告诉我什么是最优雅/最可靠的解决方案。
编辑 1:
我刚刚发现可以从 x86 应用程序读取 x64 注册表配置单元,但仅限于 .NET 4.0 及更高版本(根据我的来源,仍需要测试)。
string registryBranchPath = "SOFTWARE\MySoft";
RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
regKey = regKey.OpenSubKey(registryBranchPath);
这仅解决了我的问题的一部分,另一部分(关于在 Windows 特定的非静态类中使用 DllImport 的可能性)仍有待确认/测试。
【问题讨论】:
-
个人而言,如果我在进行单独的构建,我将有一个类(或者可能具有相同名称的克隆),其代码由编译时常量指定
-
我有点困惑。问题似乎与注册表有关,它甚至在 OSX/Linux 上都不可用。为什么不尽可能使用适用于所有平台的“设置”策略?
-
在我的应用程序中,我必须检测 CAD 引擎安装。在 linux 上我可以读取“which bricscad”命令的输出,而在 Windows 中我必须读取注册表项。
标签: c# winapi mono registry 32bit-64bit