2

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

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

win_version = Environment.OSVersion.Version.Major;

这将返回我需要的主要版本号。'6' 是 Vista/7,其他都不是,这就是我需要确定的。利用这一点,我需要确定是否在操作系统大于或等于“6”时包含 CoreAudioApi 命名空间。从研究来看,usings 需要与程序一起编译,但我也读过一些叫做反射的东西——这可能是我需要的。

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

4

2 回答 2

2

我刚刚尝试了以下方法:

  • 创建一个新的控制台应用程序项目
  • CoreAudioApi项目从 CodeProject 添加到解决方案
  • 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。当(且仅当)需要时,框架应该动态加载该程序集。

于 2012-11-08T13:54:32.047 回答
-1

COREAUDIOAPI.dll不适用于 XP 或更早版本,因为它们无法处理MMDEVICEAPI(设备枚举)。我不知道Vista。

于 2016-01-01T18:03:07.013 回答