wpf icon indicating copy to clipboard operation
wpf copied to clipboard

Imaging.CreateBitmapSourceFromHIcon crash: Value does not fall within the expected range.

Open n9 opened this issue 10 months ago • 18 comments

Description

Imaging.CreateBitmapSourceFromHIcon, when called with BitmapSizeOptions.FromHeight(16), throws ArgumentException: Value does not fall within the expected range.

Reproduction Steps

// just create a hIcon
var hIcon = new System.Drawing.Bitmap(64, 64).GetHicon();

// this will crash
var bitmapSource = Imaging.CreateBitmapSourceFromHIcon(hIcon, Int32Rect.Empty, BitmapSizeOptions.FromHeight(16));

Expected behavior

The above code will not throw an exception.

Actual behavior

The code above throws ArgumentException: Value does not fall within the expected range.

Regression?

It does not seem to be.

Known Workarounds

Do not use Imaging.CreateBitmapSourceFromHIcon with explicit BitmapSizeOptions.

Impact

Any API that uses InteropBitmap with explicit BitmapSizeOptions may be affected.

Configuration

.NET 9 / Win10 / x64

It may not, as the problem is in the managed code.

Other information

The problem seems to be caused by the InteropBitmap.FinalizeCreation method that calls:

_sizeOptions.GetScaledWidthAndHeight((uint)_sizeOptions.PixelWidth, (uint)_sizeOptions.PixelHeight, out var newWidth, out var newHeight);

I assume that the first two arguments of BitmapSizeOptions.GetScaledWidthAndHeight should contain the original image size instead of _sizeOptions.PixelWidth and _sizeOptions.PixelHeight.

n9 avatar Feb 04 '25 13:02 n9

Well spotted!

miloush avatar Feb 04 '25 13:02 miloush

Are you interested in creating a PR with a fix?

miloush avatar Feb 04 '25 13:02 miloush

I am unable to find InteropBitmap.cs in this repo.

n9 avatar Feb 04 '25 14:02 n9

https://github.com/dotnet/wpf/blob/43f4bc532d89c017567d1ba9842ffee4c439a6b8/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/InteropBitmapSource.cs#L22

miloush avatar Feb 04 '25 14:02 miloush

(you can search for InteropBitmap here on GitHub)

miloush avatar Feb 04 '25 14:02 miloush

I cloned the repo and opened it in VS. Now it is much easier.

I have mocked up a solution: https://github.com/n9/wpf/commit/623fc974ec6197f78a43254f4548e491a1f74a99, but I do not know, how to test it.

(I don't have much experience with WPF or its internals.)

n9 avatar Feb 04 '25 14:02 n9

That's a good start. I don't think you need the empty rectangle check, because the GetScaledWidthAndHeight method takes care of the case.

There is a guide at https://github.com/dotnet/wpf/blob/main/Documentation/developer-guide.md though it doesn't look very friendly to me.

You can try to run build from the command line of the cloned repository. Does it build? We might need to tweak things a bit or start with a known good branch easy for testing (such as 9.0 release).

miloush avatar Feb 04 '25 15:02 miloush

I don't think you need the empty rectangle check, because the GetScaledWidthAndHeight method takes care of the case.

If you mean this condition:

https://github.com/n9/wpf/blob/1467b5df5bee57c5cd0f179ec03d271bdb6201d1/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/InteropBitmapSource.cs#L391-L400

I do not understand, how GetScaledWidthAndHeight can handle it.

We might need to tweak things a bit or start with a known good branch easy for testing (such as 9.0 release).

I rebased the branch (commit) on the release/9.0 branch.

You can try to run build from the command line of the cloned repository. Does it build?

It failed:

  main.cpp
  UIAutomationClientSideProviders-ref -> L:\Foreign\.net\wpf\artifacts\bin\UIAutomationClientSideProviders-ref\Debug\ne
  t9.0\UIAutomationClientSideProviders.dll
  PresentationCore-ref -> L:\Foreign\.net\wpf\artifacts\bin\PresentationCore-ref\Debug\net9.0\PresentationCore.dll
  Generating Code...
  .NETCoreApp,Version=9.0.AssemblyAttributes.cpp
LINK : fatal error LNK1104: cannot open file 'MSVCURTD_netcore.LIB' [L:\Foreign\.net\wpf\src\Microsoft.DotNet.Wpf\src\D
irectWriteForwarder\DirectWriteForwarder.vcxproj]

n9 avatar Feb 04 '25 15:02 n9

It failed:

  main.cpp
  UIAutomationClientSideProviders-ref -> L:\Foreign\.net\wpf\artifacts\bin\UIAutomationClientSideProviders-ref\Debug\ne
  t9.0\UIAutomationClientSideProviders.dll
  PresentationCore-ref -> L:\Foreign\.net\wpf\artifacts\bin\PresentationCore-ref\Debug\net9.0\PresentationCore.dll
  Generating Code...
  .NETCoreApp,Version=9.0.AssemblyAttributes.cpp
LINK : fatal error LNK1104: cannot open file 'MSVCURTD_netcore.LIB' [L:\Foreign\.net\wpf\src\Microsoft.DotNet.Wpf\src\D
irectWriteForwarder\DirectWriteForwarder.vcxproj]

That started like two weeks ago; using VS Developer prompt and running the build from there should work just fine though.

Or you can just build it directly if you use the start-vs.cmd in preview, that way you can also run tests via Test Explorer.

h3xds1nz avatar Feb 04 '25 16:02 h3xds1nz

VS Developer prompt does not help:

Image

n9 avatar Feb 04 '25 16:02 n9

the msvcurtd_netcore.lib is part of the MSVC, perhaps you are missing some of the components of VS from the developer guide?

miloush avatar Feb 04 '25 16:02 miloush

Maybe. I just cloned the repo, opened in VS (it installed MSVC). And then after suggestion run build.cmd in the VS Developer prompt.

Image

If I create a draft of PR, will Github build and test it?

n9 avatar Feb 04 '25 17:02 n9

I would suggest you import the https://github.com/dotnet/wpf/blob/main/Documentation/wpf.vsconfig into the VS installer. If I had to take a guess, it would be the C++/CLI support.

GitHub will probably build it but not test it. It is a good practice (and PR acceptance criteria) to make sure your changes compile and do what you expect.

miloush avatar Feb 04 '25 18:02 miloush

@n9 Looks like you are working on this issue, hence assigning it to you.

himgoyalmicro avatar Feb 05 '25 05:02 himgoyalmicro

Alright, so from my binlogs:

When building via dev prompt (that works), the linker command used is:

CommandLineArguments = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\bin\HostX86\x86\link.exe /ERRORREPORT:QUEUE /OUT:"C:\Users\somebody\wpf\artifacts\bin\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\lib\x86\\" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\UCRT\x86\\" /LIBPATH:"C:\Users\somebody\.nuget\packages\microsoft.netcore.app.host.win-x86\10.0.0-preview.2.25079.6\runtimes\win-x86\native" /WX kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FULL /PDB:"C:\Users\somebody\wpf\artifacts\bin\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.pdb" /ASSEMBLYDEBUG /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /FIXED:NO /NXCOMPAT /MACHINE:X86  /keyfile:C:\Users\somebody\.nuget\packages\microsoft.dotnet.arcade.sdk\10.0.0-beta.25080.7\tools\snk/35MSSharedLib1024.snk /delaysign /DLL Shlwapi.lib
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\ExtendedNativeVersion.res
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\precomp.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\dwriteloader.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\Utils.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\main.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\OtherAssemblyAttrs.obj
"C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\.NETCoreApp,Version=10.0.AssemblyAttributes.obj"

When building via standard command line (which fails), the linker command line is:

CommandLineArguments = C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.43.34808\bin\HostX86\x86\link.exe /ERRORREPORT:QUEUE /OUT:"C:\Users\somebody\wpf\artifacts\bin\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.43.34808\lib\x86\\" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\UCRT\x86\\" /LIBPATH:"C:\Users\somebody\.nuget\packages\microsoft.netcore.app.host.win-x86\10.0.0-preview.2.25079.6\runtimes\win-x86\native" /WX kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FULL /PDB:"C:\Users\somebody\wpf\artifacts\bin\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.pdb" /ASSEMBLYDEBUG /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /FIXED:NO /NXCOMPAT /MACHINE:X86  /keyfile:C:\Users\somebody\.nuget\packages\microsoft.dotnet.arcade.sdk\10.0.0-beta.25080.7\tools\snk/35MSSharedLib1024.snk /delaysign /DLL Shlwapi.lib
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\ExtendedNativeVersion.res
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\DirectWriteForwarder.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\precomp.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\dwriteloader.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\Utils.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\main.obj
C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\OtherAssemblyAttrs.obj
"C:\Users\somebody\wpf\artifacts\obj\DirectWriteForwarder\Debug\net10.0\.NETCoreApp,Version=10.0.AssemblyAttributes.obj"

So yeah, as we during local build just use whatever is currently set in the environment for MSVC (where the latest installation of whatever update on Visual Studio always overrides), my environment was overriden by my latest Preview installation and that was missing C++/CLI support for the latest version (which is where msvcurtd_netcore.lib and msvcurt_netcore.lib come from).

So @n9 looking at your screenshot, please install C++/CLI support for v143 build tools as @miloush previously suggested, I'm just happy to confirm it shall fix your issue.

h3xds1nz avatar Feb 07 '25 09:02 h3xds1nz

@h3xds1nz and @miloush

Thank you, C++/CLI support for v143 build tools fixed it.

I also fixed two cast issues in the code and now the build succeeds.

n9 avatar Feb 28 '25 21:02 n9

@n9 are you still planning to raise your PR? If not, I'm happy to do it.

h3xds1nz avatar Mar 21 '25 21:03 h3xds1nz

@h3xds1nz Unfortunately, I don't have much time at the moment to create a PR. (Feel free to use my commit: https://github.com/n9/wpf/commit/cc849d54797dc9e7d20e5ccb94d802fb641349b3.)

n9 avatar Mar 22 '25 13:03 n9