
Interoperating with unmanaged code
.NET applications are loaded, executed, and managed by the CLR. We use the term unmanaged to refer to any code that is outside the control of the CLR.
If a .NET developer needs to interact with unmanaged code, they can use two technologies: Component Object Model (COM) Interop and Platform Invoke (also known as P/Invoke).
Tip
Both of these technologies are specific to Windows and, therefore, are only supported by the .NET Framework, not by the .NET Core.
Automating Microsoft Excel using COM Interop
Most of the popular Microsoft Office products support being automated using COM. If you have Microsoft Excel (for Windows) installed, then you can complete this exercise.
Add a new console application project named Ch05_AutomatingExcel. In the Solution Explorer window, right-click on References and choose Add Reference….
In the Reference Manager window, on the left-hand side, click on COM, and then select the checkbox for Microsoft Excel 16.0 Object Library (or the latest version that you have installed). Click on OK:

At the top of the code, import the following types and namespaces:
using static System.Console; using static System.Convert; using Microsoft.Office.Interop.Excel;
In the Main
method, enter the following statements:
const int xlPie = 5; Write("Enter a number: "); double number = ToDouble(ReadLine()); var excel = new Application(); excel.Visible = true; excel.Workbooks.Add(); excel.Range["A1"].Value = number; excel.Range["A2"].Formula = "=A1*2"; excel.Range["A1:A2"].Select(); excel.ActiveSheet.Shapes.AddChart2(251, xlPie).Select(); excel.ActiveChart.SetSourceData(Source: excel.Range["Sheet1!$A$1:$A$2"]);
When you run the console application, it starts Excel, makes it visible (because it runs hidden in the background by default), adds a blank new workbook, sets the cell A1
to contain the number the user entered, doubles it using a formula, then selects the cells and uses the numbers as a source for a pie chart:
Tip
To make it even easier to learn how to automate Excel, switch on the Developer tab in Excel and then use it to record a macro. The code recorded is Visual Basic for Applications, but that is easy to translate to C#.

Accessing the Win32 API with P/Invoke
All Windows applications make calls to the Win32 API to provide their functionality. That's what makes them Windows applications.
Technologies such as .NET are layers on top of the Win32 API. Most of the Win32 API functions have been exposed via .NET types, but not all. If a .NET developer needs to access a Win32 API that isn't already exposed, then they can use P/Invoke.
Add a new console application project named Ch05_HackNotepad. At the top of the file, import the following types and namespaces:
using static System.Console; using static System.Diagnostics.Process; using System.Runtime.InteropServices; using System;
In the Program
class, enter the following statements:
[DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool SetWindowText(IntPtr hwnd, string lpString);
In the Main
method, enter the following statements:
Write("Enter a message: "); string message = ReadLine(); WriteLine("Press any key to start Notepad."); ReadKey(); Start("notepad.exe").WaitForInputIdle(); // use a Win32 API call to get reference to Notepad IntPtr notepad = FindWindow("Notepad", null); if (notepad != IntPtr.Zero) { // if it is running, set it's window text with a message SetWindowText(notepad, "Notepad has been hacked! " + message); } else { WriteLine("Notepad is not running!"); }
When you run the console application, it prompts the user to enter a message, starts an instance of Notepad, finds the Notepad window, and sets its title to a customized message.
Tip
A more practical example would be impersonating a user other than the current one while executing some statements. To do this, you would need to use P/Invoke to import the LogonUser
function from advapi32.dll
and the CloseHandle
function from kernel32.dll
. For more details, visit https://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.110).aspx.