- Windows Native APIs
- .NET Classes
- Calling Windows Native APIs – Script Example
Windows Native APIs:
“Application Programming Interfaces” works for developers take advantage of built-in available operations to work with their software. This helps reduce the amount of code developers need to create, and also helps create more consistency across apps for the same platform. APIs can control access to hardware and software resources.
The Windows Native API serves one purpose: as a means for calling operating system services located in kernel mode in a controlled manner. Kernel mode is where the core of Windows executes and it’s in kernel mode that components have direct access to hardware and services that perform management of the computer’s resources including memory, devices and processes.
The process of writing a .NET application consists of building blocks, each of these blocks are containers for member types, let me use a metaphor to better explain.
Imagine your computer mouse as a .NET class, what kind of member types would it have?
Data: Shape, color, size, buttons…
Functions: Click, Move cursor
So, our mouse class example has two member types, Data and Function, data refers to properties and functions to methods.
Why does it matter for Powershell?
Powershell is about dealing with .NET Objects, that’s one of the main powers of Powershell, you must know that to dive deep into it.
The Get-Service cmdlet returns a list of services in the system, these services are objects which we can control with ServiceController class.
Get-Service | Get-Member
Data: Whether it is a string, integer or another object.
Functions: A set of instructions that are run with or without parameters.
Keep in mind that Powershell automate things from .NET framework, in this example we’ve seen that the .NET class behind the Get-Service cmdlet is the ServiceController Class.
To confirm this, we can use the syntax [typename]::StaticMethod(), this is how we call static methods from .NET classes in a powershell session.
#Static methods can be accessed directly via the class, without the need of an object. [System.ServiceProcess.ServiceController]::GetServices()
If you run this line in your Powershell session, you’ll see that it returns the same list of services of Get-Service cmdlet, note that this is possible only because we ran the Get-Service before, which automatically loaded the assembly that contains the class, otherwise we should load it with Add-Type -AssemblyName System.ServiceProcess
In this case the AssemblyName is the same as the namespace that contains the ServiceController class, but that’s not a rule, assemblies can have different names from the namespace.
We’ve seen that classes are containers for data and functions, namespaces are containers for related classes.
For better maintainability, as an application grows in size, we need several namespaces to group related classes, reducing the change of name collisions. A namespace can contain other namespaces, in this case the namespace is System.ServiceProcess.
Assemblies are physical separated related namespaces, they are represented by files (DLL or EXE) that contains one or more namespaces and classes. A DLL is a file that includes code that can be re-used across different programs, while EXE is a file that represents a program that can be executed.
Calling Windows Native APIs
$Signature = @" [DllImport("user32.dll")]public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); "@ $ShowWindowAsync = Add-Type -MemberDefinition $Signature -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru # Minimize the Windows PowerShell console $ShowWindowAsync::ShowWindowAsync((Get-Process -Id $pid).MainWindowHandle, 2) # Restore it $ShowWindowAsync::ShowWindowAsync((Get-Process -Id $Pid).MainWindowHandle, 4)
The commands in this example demonstrate how to call native Windows APIs in Windows PowerShell. Add-Type uses the Platform Invoke (P/Invoke) mechanism to call a function in User32.dll from Windows PowerShell.
See example 5 in this reference: docs.microsoft.com
PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke* signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs.
Notes is a category of this blog which serves to briefly introduce you in a more complex subject, the purpose is to link these notes to articles that contains such subjects for a better understanding, see more about it in My notes category.