Calling Win32 DLLs in C# Using InteropServicesCalling Win32 DLLs via methods imported from a non-managed Win32 API using Platform Invocation Services (PInvoke) from C#.
How to import methods from a non-managed Win32 API call using Platform Invocation Services (PInvoke). PInvoke allows managed code to call unmanaged methods that are implemented in a DLL.
There are two ways that your C# code can directly call unmanaged code (code which .Net cannot see or have access to), a direct call to a function exported from a DLL or through a call to an interface method on a COM object. This tutorial deals with the former technique; the latter will be covered in a future tutorial.
To call an external unmanaged method, you must provide .Net with a declaration of the unmanaged method, and a description of how to marshal (use) the parameters and return value to and from the unmanaged code.
This shortcode sample will invoke a method called "PlaySound" from a DLL called "winmm.dll".
Firstly, you need to add a reference to System.Runtime.InteropServices
using System.Runtime.InteropServices;
Next, we need to provide a declaration of the unmanaged code using the DllImport attribute. This tells .Net that the function is contained within a DLL called winmm.dll. This is a Windows built-in file and is found in the system path so you do not need to specify its full location.
[DllImport("winmm.dll")]
public static extern bool PlaySound(string filename,long hmodule, int dword );
Notice that the methods are static (we do not have a class to instantiate) and we use the extern keyword which informs the compiler that the methods are external to the runtime.
All that is left to do now is to call the methods with parameters. The .Net Framework does not contain the flag's header information, so you must either declare them yourself or locate and use the bitwise values. In this example 0x0001 represents the old Win32 flag "SND_FILENAME
" and 0x00020000
represents "SND_ASYNC
". You can find these values on the Windows API website.
The final code looks like this:
using System;
using System.Runtime.InteropServices;
class PInvokeTest
{
[DllImport("winmm.dll")]
public static extern bool PlaySound(string pszSound, UIntPtr hmod, uint fdwSound);
public static void Main()
{
bool result;
result = PlaySound("C:\WINDOWS\Media\Chimes.wav", UIntPtr.Zero, 0x0001 | 0x00020000);
Console.WriteLine(result);
}
}
For a list of Win32 functions and parameters please refer to the Windows API Reference on the Microsoft site.
How to Beep the Internal PC Speaker in C# using Win32
This short snippet uses a system DLL call to legacy Win32 API which will sound the PC speaker at a given frequency and duration.
[DllImport("Kernel32.dll")]
public static extern bool Beep(UInt32 frequency, UInt32 duration);
public static void BeepMe()
{
int Frequency = 500;
int DurationInMS = 100;
Beep(Frequency, DurationInMS);
}
Cannot Beep PC Speaker in Windows 7 and Up?
As of Windows 7, 64-bit versions of Windows don't support the internal PC speaker beeps. At all. This code and Console.Beep will simply use the default sound device configured in Windows. See here for details - What's up with the Beep driver in Windows 7?