I’m trying to use PowerShell to change a Window title to display emojis.
I can change the Window title of a process (that has a window) using…
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class Win32 {
[DllImport("User32.dll", EntryPoint="SetWindowText")]
public static extern int SetWindowText(IntPtr hWnd, string strTitle);
}
"@
$MyNotepadProcess = start-process notepad -PassThru
[Win32]::SetWindowText($MyNotepadProcess.MainWindowHandle, 'My Title')
But using SetWindowTextW just garbles the output…
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class Win32 {
[DllImport("User32.dll", EntryPoint="SetWindowTextW")]
public static extern int SetWindowTextW(IntPtr hWnd, string strTitle);
}
"@
$MyNotepadProcess = start-process notepad -PassThru
[Win32]::SetWindowTextW($MyNotepadProcess.MainWindowHandle, 'My Title')
One issue I think I have, is that SetWindowTextW only accept wide string, but I don’t know how to provide that as input.
And then I need to add the emojis using the UniCode numbers as in `u{1F600} (that’s a 🙂 too you).
(See Get Started with Win32 and C++ – Working with Strings)
>Solution :
The simplest way to ensure that the Unicode version of a WinAPI function is called properly is to:
-
Add
CharSet=CharSet.Unicodeto the[DllImport]attribute. -
Omit the
Wsuffix from the function name.
// Note the use of "CharSet=CharSet.Unicode" and
// the function name *without suffix*
[DllImport("User32.dll", CharSet=CharSet.Unicode)]
public static extern int SetWindowText(IntPtr hWnd, string strTitle);
This ensures that SetWindowTextW, i.e. the Unicode implementation of the function is called, and that .NET marshals the .NET string essentially as-is as as a native LPCWSTR string, i.e. as a null-terminated array of Unicode code units.

