c# - 使用反射在某些操作系统上使用命名空间

标签 c# .net reflection

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

我创建了这个函数来获取当前环境的版本号:

win_version = Environment.OSVersion.Version.Major;

这会返回我需要的主要版本号。 '6' 是 Vista/7,其他都不是,这是我需要确定的。利用这一点,如果操作系统大于或等于“6”,我需要确定是否包含 CoreAudioApi 命名空间。根据研究,usings 需要与程序一起编译,但我也读过一些叫做 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/

相关文章:

java - 是否可以通过类名获取静态属性?

c# - 使用反射从属性名称中获取 lambda 表达式

c# - Firebase 存储 : How to get a download link? C#

c# - 没有 VS 2008 的 system.dllnotfoundexception

c# - 搜索拥有超过输入数字的关注者的推特用户

.net - .NET 中的 DoEvents

c# - 如何通过反射获取字符串属性的值?

c# - 如何通过 Entity Framework 存储可变二维数组?

c# - 简化条件if语句c#

.net - 在 .Net 中进行跟踪的工具/最佳实践