我正在创建一个使用 CodeProject CoreAudioApi(非常流行的音频处理框架)的程序,但问题是 CoreAudioApi 使用的系统调用在 Vista 之前的任何 Windows 版本中都不可用。如果我运行一个编译了 CoreAudioApi 的程序(像往常一样使用 using
语句),该程序将在 Vista 之前的任何版本上崩溃。
我创建了这个函数来获取当前环境的版本号:
win_version = Environment.OSVersion.Version.Major;
这会返回我需要的主要版本号。 '6' 是 Vista/7,其他都不是,这是我需要确定的。利用这一点,如果操作系统大于或等于“6”,我需要确定是否包含 CoreAudioApi 命名空间。根据研究,using
s 需要与程序一起编译,但我也读过一些叫做 Reflection 的东西——这可能是我需要的。
一旦我得到 CoreAudioApi 命名空间 using
'd(抱歉缺少术语),剩下的就很简单了。我该怎么做?
长话短说 我需要某种形式的代码来有效地做到这一点:
using System;
using System.Text;
//etc
if(currentWindowsVersion>=6) using CoreAudioApi;
除了控制结构在类之外不起作用,所有命名空间都随程序一起编译,而不是单独控制。
谢谢!
编辑:到目前为止,我使用它来加载 CoreAudioApi 命名空间作为已编译的程序集:
if(win_version>=6){
CoreAudioApi = Assembly.LoadFrom("CoreAudio.dll");
CoreAudioApi.GetLoadedModules();
CoreAudioApi.GetTypes();
MessageBox.Show("Loaded CoreAudioApi");
}
从这里开始,我需要做的是实际使用 API 中的类型和方法。我在 Windows Vista/7 上运行的代码是这样的:
public static MMDeviceEnumerator devEnum;
public static MMDevice defaultDevice;
//later in a mute method:
defaultDevice.AudioEndpointVolume.Mute = true/false;
我什至真的不需要 devEnum AFAIK,所以真正重要的只有最后两行(除了评论)。
最佳答案
我刚刚尝试了以下方法:
- 创建一个新的控制台应用程序项目
- 将 CodeProject 中的
CoreAudioApi
项目添加到解决方案中 - 在我的控制台应用程序中添加对
CoreAudioApi
的项目引用 - 创建以下类:
interface IAudio { void SetVolume(float level); }
class XpAudio : IAudio {
public void SetVolume(float level) {
// I do nothing, but this is where your old-style code would go
}
}
class VistaAudio : IAudio {
public void SetVolume(float level) {
MMDeviceEnumerator devEnum = new MMDeviceEnumerator();
MMDevice defaultDevice = devEnum
.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
defaultDevice.AudioEndpointVolume.MasterVolumeLevel = level;
}
}
class Program {
static void Main(string[] args) {
IAudio setter = Environment.OSVersion.Version.Major >= 6
? (IAudio)new VistaAudio()
: (IAudio)new XpAudio();
float val = float.Parse(Console.ReadLine());
setter.SetVolume(val);
Console.ReadLine();
}
}
这在我的服务器(~ Windows 7)和本地(Windows XP)机器上运行。在我的 XP 机器上,它会很高兴地接受一个值并忽略它;在我的服务器上,它抛出一个异常,(大概是因为我没有声音输出)。如果我让我的 XP 机器运行 CoreAudioApi
,当我输入一个值时,我得到一个异常,而不是之前。
问题是,您以不同的方式做了哪些事情来让您的应用程序中断?您是否在启动时使用了 CoreAudioApi
代码?
编辑:在看到您的编辑后,如果您这样做,您根本不需要弄乱 Assembly.LoadFrom
。框架应该动态在需要时(且仅当)加载该程序集。
关于c# - 使用反射在某些操作系统上使用命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13289829/