Scott
Scott

Reputation: 5389

Using Reflection to use a namespace on certain OSs

I'm creating a program that uses the CodeProject CoreAudioApi (pretty popular framework for manipulating audio), but the problem is the CoreAudioApi uses system calls that aren't available in any versions of Windows earlier than Vista. If I run a program with CoreAudioApi compiled with it (using a using statement as normal), the program will crash on anything earlier than Vista.

I've created this function to get the version number of the current environment:

win_version = Environment.OSVersion.Version.Major;

That returns the major version number I need. '6' is Vista/7, anything else is not, which is all I need to determine. Utilizing this, I need to determine whether or not to include the CoreAudioApi namespace if the OS is over or equal to '6'. From research, usings need to be compiled with the program, but I've also read about something called Reflection - which might be what I need.

Once I get the CoreAudioApi namespace using'd (sorry for the lack of terminology), the rest is easy. How can I do this?

TL;DR I need some form of code that would effectively do this:

using System;
using System.Text;
//etc
if(currentWindowsVersion>=6) using CoreAudioApi;

Except control structures won't work outside of a class, and all namespaces are compiled with the program, not controlled individually.

Thanks!


EDIT: So far, I'm using this to load the CoreAudioApi namespace as a compiled assembly:

if(win_version>=6){
    CoreAudioApi = Assembly.LoadFrom("CoreAudio.dll");
    CoreAudioApi.GetLoadedModules();
    CoreAudioApi.GetTypes();
    MessageBox.Show("Loaded CoreAudioApi");
}

From here, what I need to do is actually use the types, and methods from the API. My code that works on Windows Vista/7 is this:

public static MMDeviceEnumerator devEnum;
public static MMDevice defaultDevice;
//later in a mute method:
defaultDevice.AudioEndpointVolume.Mute = true/false;

I don't even really need devEnum AFAIK, so really the only important lines are the last two (besides the comment).

Upvotes: 2

Views: 315

Answers (2)

VBNETcoder
VBNETcoder

Reputation: 61

COREAUDIOAPI.dll does not work on XP or earlier, because they cant handle MMDEVICE API (Device Enumeration). I dont know about Vista.

Upvotes: -1

Rawling
Rawling

Reputation: 50114

I've just tried the following:

  • Create a new console application project
  • Add the CoreAudioApi project from CodeProject to the solution
  • Add a project reference to CoreAudioApi in my console app
  • Create the following classes:
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();
    }
}

This runs on both my server (~ Windows 7) and local (Windows XP) machines. On my XP machine it'll happily take in a value and ignore it; on my server, it throws an exception, (presumably because I don't have a sound output). If I make my XP machine run the CoreAudioApi, I get an exception when I input a value, not before.

The question is, what are you doing differently to make your application break? Are you using CoreAudioApi code at startup?

EDIT: After seeing your edit, if you do this, you shouldn't need to mess about with Assembly.LoadFrom at all. The framework should dynamically load that assembly if (and only if) and when it needs to.

Upvotes: 2

Related Questions