Calling Win32 DLLs in C# Using InteropServices

Calling Win32 DLLs via methods imported from a non-managed Win32 API using Platform Invocation Services (PInvoke) from C#.

By Tim TrottC# ASP.Net MVC • November 28, 2011
Calling Win32 DLLs in C# Using InteropServices

How to import methods from a non-managed Win32 API call using Platform Invocation Services (PInvoke). PInvoke allows managed code to call unmanaged methods 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 "PlaySound" method from a DLL called "winmm.dll".

Firstly, you need to add a reference to System.Runtime.InteropServices

C#
using System.Runtime.InteropServices;

Next, we must declare 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 found in the system path, so you do not need to specify its full location.

C#
[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 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:

C#
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.

Internal PC Speaker
Internal PC Speaker
C#
[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?

About the Author

Tim Trott is a senior software engineer with over 20 years of experience in designing, building, and maintaining software systems across a range of industries. Passionate about clean code, scalable architecture, and continuous learning, he specialises in creating robust solutions that solve real-world problems. He is currently based in Edinburgh, where he develops innovative software and collaborates with teams around the globe.

Related ArticlesThese articles may also be of interest to you

CommentsShare your thoughts in the comments below

My website and its content are free to use without the clutter of adverts, popups, marketing messages or anything else like that. If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.

This post has 4 comments. Why not join the discussion!

New comments for this post are currently closed.