wpf: Calls to comctl32.dll succeed in .NET 4.8, but fail in .NET 5 with System.EntryPointNotFoundException
- .NET Core Version: 5.0.100 and 3.1.404
- Windows version: Windows 10 (18363.1139)
- Does the bug reproduce also in WPF for .NET Framework 4.8?: No
- Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc…)? No
Problem description:
Calls to comctl32.dll
succeed in .NET Framework 4.8, but fail in .NET 5 and also in .NET Core 3.1 with a System.EntryPointNotFoundException
.
e.g.
[DllImport("comctl32.dll", PreserveSig = false)]
private static extern void TaskDialogIndirect([In] ref TaskDialogConfig pTaskConfig, out int pnButton,
out int pnRadioButton, [MarshalAs(UnmanagedType.Bool)] out bool pfVerificationFlagChecked);
// ...
var config = new TaskDialogConfig
{
pszWindowTitle = "Task dialog title",
pszMainInstruction = "Task dialog main instruction",
dwCommonButtons = TaskDialogCommonButtonFlags.OkButton | TaskDialogCommonButtonFlags.CancelButton,
// ...
};
using (new ComCtlv6ActivationContext(enable: true))
{
TaskDialogIndirect(ref config, out _, out _, out _);
}
Actual behavior:
System.EntryPointNotFoundException: Unable to find an entry point named 'TaskDialogIndirect' in DLL 'comctl32.dll'.
at TaskDialogApi.TaskDialog.TaskDialogIndirect(TaskDialogConfig& pTaskConfig, Int32& pnButton, Int32& pnRadioButton, Boolean& pfVerificationFlagChecked)
Expected behavior:
Display the Task Dialog requested
Minimal repro:
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 1
- Comments: 28 (23 by maintainers)
I have no idea who added the manifest in .NET Framework, I just want to clarify that the fact that it lives next to
mscorlib
is probably not very telling. There are more than 400 files next tomscorlib
in .NET Framework…That said I think this is something which should ideally work “seamlessly” whenever “Windows Dektop” is asked for. For example, it might make sense to automatically include this in the application manifest for any app which targets
net5-windows
(ornet6-windows
).Well - it’s already in runtime repo right now 😉 Depending on the design it might not belong there. For example if we were to implement the solution where windows apps get different manifest by default, it would probably belong to the SDK repo.
But I think there’s a discussion to have:
XPTheme.manifest
in the shared framework (next to coreclr.dll and other “root” assemblies). This doesn’t feel right to be honest, since we would have to do this for all apps, not just net5-windows apps - any app on windows regardless of its purpose would get that file.@vatsan-madhavan I’m just saying that the affected domain is (.NET apps that want to use ComCtl32) - (WinForms apps). I make no claims as to whether that set is equal to (WPF apps). Even if that were true today, there’s no guarantee it will be true in the future. Thus it’s prudent to treat this as a “non-WinForms” problem rather than as a WPF problem, and solve it at a deeper level than WPF.
Also, it’s possible that other cases will arise of .NET apps that want to use some technology unknown to WPF or WinForms or any specific .NET subframework/component, requiring a manifest or similar app-level enabler. It shouldn’t be WPF’s job to solve these cases. Set the right precedent now.
@RussKie I think that guys here want
XPThemes.manifest
to be delivered separately. For now, wpf completely haven’t it and in winforms it’s embedded in winforms.dll.The app tries to load the required manifest itself, here. This code looks for a file named “XPThemes.manifest” next to mscorlib.dll, whose location it determines by
typeof(object).Assembly.Location
. You’re seeing three cases:This is an app bug, not WPF. The app assumes something that is true in .NET Framework but not in .NET Core, namely that “XPThemes.manifest” lives next mscorlib.dll. Whether that assumption should hold is a question for .NET runtime; WPF has no stake, and no reason to load an equivalent manifest the way WinForms does.
The workaround is going to be the same, but the underlying issue is probably very different. dotnet/runtime#42593 is about WinForms which has code to enable comctl32 APIs on app start. WPF doesn’t seem to have that code. I don’t know why it works on .NET Framework - the application doesn’t have the needed section in its manifest there either. Somebody from WPF should look into this and determine how it worked in .NET Framework and how/if should work in .NET Core.
WinForms does carry the manifest in .NET Core, but it’s a resource in the winforms dll. You can see how WinForms solved a problem around single-file, by extracting the that resource to disk and loading it as a manifest - https://github.com/dotnet/winforms/pull/4149/files#diff-4bb832ea247560f6b393cd7989713d833469e8b70c47961b086a88b5345439aeR834-R838.
In .NET Framework, XPThemes.manifest was supplied by either WinForms or the runtime in a location adjacent to mscorlib.dll.
In .NET Core, WindowsDesktop framework forgot to provide XPThemes.manifest adjacent to mscorlib.dll - this is a compat break between .NET Framework and .NET Core.
Whether WinForms or runtime makes it available again is a good question to discuss and resolve. I recommend moving this issue to winforms rather than just closing it.
/cc @dotnet/dotnet-winforms
@SamBent will look at the manifest loading for .NET Framework to see why this works there. Thanks.