unoplatform/uno · critical · InvalidOperationException
PInvoke.CreateWindowEx failed: {Win32Helper.GetErrorMessage(
Error message
PInvoke.CreateWindowEx failed: {Win32Helper.GetErrorMessage()} What it means
InvalidOperationException thrown in the instance constructor of Win32MediaPlayerPresenterExtension when CreateWindowEx returns a null HWND, meaning the child window hosting the LibVLC surface could not be created. The window class must already be registered (error 30) for CreateWindowEx to succeed.
Source
Thrown at src/AddIns/Uno.UI.MediaPlayer.Skia.Win32/Win32MediaPlayerPresenterExtension.cs:87
_extForNextCreateWindow = new WeakReference<Win32MediaPlayerPresenterExtension>(this);
_hwnd = PInvoke.CreateWindowEx(
0,
lpClassName,
new PCWSTR(),
0,
PInvoke.CW_USEDEFAULT,
PInvoke.CW_USEDEFAULT,
PInvoke.CW_USEDEFAULT,
PInvoke.CW_USEDEFAULT,
HWND.Null,
HMENU.Null,
Win32Helper.GetHInstance(),
null);
_extForNextCreateWindow = null;
if (_hwnd == HWND.Null)
{
throw new InvalidOperationException($"{nameof(PInvoke.CreateWindowEx)} failed: {Win32Helper.GetErrorMessage()}");
}
if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Trace))
{
this.Log().Trace("Created media player window.");
}
var success = PInvoke.RegisterTouchWindow(_hwnd, 0);
if (!success && this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error))
{
this.Log().Error($"{nameof(PInvoke.RegisterTouchWindow)} failed: {Win32Helper.GetErrorMessage()}");
}
var cp = new ContentPresenter { Content = new Win32NativeWindow(_hwnd) };
_presenter.Child = cp;
cp.SizeChanged += (_, _) => StretchChanged();
}
View on GitHub (pinned to 0418340488)
Solutions
- Inspect Win32Helper.GetErrorMessage() in the exception — common codes: ERROR_INVALID_WINDOW_HANDLE (1400), ERROR_NOT_ENOUGH_MEMORY (8), access-denied on the desktop.
- Ensure the process runs on an interactive window station/desktop (not session 0 / service).
- Confirm the window class atom from RegisterClassEx is valid (if 30 failed first, 31 follows).
- Reduce simultaneous window creation if hitting GDI/user object limits.
- Update the Uno.UI.MediaPlayer.Skia.Win32 add-in to the latest version.
Example fix
// No API tweak changes CreateWindowEx outcome; guard the environment.
if (Environment.UserInteractive)
{
_presenter = new Win32MediaPlayerPresenterExtension(mediaPresenter);
} Defensive patterns
Strategy: validation
Validate before calling
// Verify an interactive desktop before constructing the media window
if (OperatingSystem.IsWindows() && Environment.UserInteractive)
_presenter = new Win32MediaPlayerPresenterExtension(mediaPresenter); Type guard
bool CanCreateWin32MediaWindow()
=> OperatingSystem.IsWindows() && Environment.UserInteractive; Try / catch
try { _presenter = new Win32MediaPlayerPresenterExtension(mediaPresenter); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CreateWindowEx"))
{ Log.Error($"Win32 media window creation failed: {ex.Message}"); } Prevention
- Ensure the process has a window station/desktop with create-window rights.
- Check the class atom from RegisterClassEx succeeded first (error 30).
- Avoid headless/service contexts for media playback.
When it happens
Trigger: Constructing Win32MediaPlayerPresenterExtension (on first media playback on Skia.Win32) when CreateWindowEx fails: the registered class is invalid, hInstance mismatch, the process lacks a window station/desktop, or extended styles are rejected. GetErrorMessage() gives the OS error code.
Common situations: Running the Skia Win32 media player in a headless/service context without an interactive desktop; a race where the window class registration partially failed; insufficient GDI/user objects; antivirus hooking window creation. The companion RegisterClassEx (error 30) typically succeeds first.
Related errors
- PInvoke.RegisterClassEx failed: {Win32Helper.GetErrorMessage
- XLIB ERROR: Cannot connect to X server
- MediaPlayerPresenterExtension must be initialized with a Med
- Playlist Items could not be set
- Unsupported media source type
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/4e8e3b102e4f5d56.
Report an issue: GitHub.