使用Reflection在某些操作系统上使用命名空间

时间:2012-11-08 13:28:31

标签: c# .net reflection

我正在创建一个使用CodeProject CoreAudioApi(非常流行的操作音频框架)的程序,但问题是CoreAudioApi使用的系统调用在Vista之前的任何Windows版本中都不可用。如果我运行一个用它编译的CoreAudioApi程序(正常使用using语句),程序将在Vista之前的任何程序崩溃。

我已创建此函数以获取当前环境的版本号:

win_version = Environment.OSVersion.Version.Major;

返回我需要的主要版本号。 '6'是Vista / 7,其他任何东西都不是,这是我需要确定的。利用这个,我需要确定是否包含CoreAudioApi命名空间,如果操作系统超过或等于'6'。从研究开始,using需要与程序一起编译,但我也读过一些名为Reflection的东西 - 这可能是我需要的东西。

一旦我获得了CoreAudioApi名称空间using'(对于缺少术语而感到抱歉),其余的很容易。我怎么能这样做?

TL; DR 我需要某种形式的代码来有效地做到这一点:

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,所以真正唯一重要的是最后两行(除了评论)。

2 个答案:

答案 0 :(得分:2)

我刚试过以下内容:

  • 创建新的控制台应用程序项目
  • 将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。该框架应该动态加载该程序集if(并且仅当)以及何时需要。

答案 1 :(得分:-1)

COREAUDIOAPI.dll无法在XP或更早版本上运行,因为它们无法处理MMDEVICE API(设备枚举)。我不知道Vista。