2012-11-08 21 views
2

我正在創建一個使用CodeProject CoreAudioApi(用於操縱音頻的非常流行的框架)的程序,但問題是CoreAudioApi使用的系統調用在任何版本的Windows早於Vista。如果我使用CoreAudioApi編譯程序(正常情況下使用using語句),程序會在早於Vista的任何程序上崩潰。使用反射在某些操作系統上使用名稱空間

我創建這個函數來獲取當前環境的版本號:

win_version = Environment.OSVersion.Version.Major; 

返回主版本號,我需要。 '6'是Vista/7,其他都不是,這是我需要確定的。利用這個,如果操作系統大於或等於'6',我需要確定是否包含CoreAudioApi命名空間。從研究中,using需要與程序一起編譯,但我也讀過一些名爲Reflection的內容 - 這可能是我需要的。

一旦我得到CoreAudioApi命名空間using'd(對於缺乏術語感到抱歉),其餘的很容易。我怎樣才能做到這一點?

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據我所知,所以真的是唯一重要的線是最後兩個(除了評論)。

+1

你不能這樣使用'''',你需要動態加載你的程序集,看看http://msdn.microsoft.com/en-us/library/xbe1wdx9.aspx 具體來說,'' LoadFrom(string path)'方法及其替代方法。 – Davio

+0

稍微偏離主題,但通過'Environment.OSVersion.Version.Major'獲取主要版本號要簡單得多。 –

+0

@SteveDanner更加方便,謝謝! – Scott

回答

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混在一起。框架應該動態如果(且僅當)和需要時加載該程序集。

+0

它似乎工作,但: 1)如何設置這樣的音量? 2)如果CoreAudioApi甚至在Windows XP上使用,它會崩潰,無論它是否使用它。 – Scott

+0

@Jaxo我假設你的程序一旦運行就會崩潰,而不是一旦它嘗試設置音量?在這種情況下,我不知道我在說些什麼,而這個答案是垃圾:) – Rawling

+0

吶,我無法弄清楚這些東西了。我嘗試編譯一個.dll文件並使用Reflection將其作爲程序集加載,但它並不按我希望的方式運行。雖然謝謝! – Scott

-1

COREAUDIOAPI.dll在XP或更低版本上無法正常工作,因爲它們無法處理MMDEVICE API(設備枚舉)。我不知道Vista。

相關問題