unoplatform/uno · critical · InvalidOperationException
PInvoke.CreateWindowEx failed
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.
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
- XLIB ERROR: Cannot connect to X server
- IMediaSource is not supported
- IRandomAccessStream is not supported
- IStorageFile is not supported
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/4e8e3b102e4f5d56.
Report an issue: GitHub.
Appendix: 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)