Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.4.2 adds reference to Microsoft.WindowsDesktop.App #353

Closed
Nefarion opened this issue Dec 2, 2021 · 29 comments
Closed

Version 1.4.2 adds reference to Microsoft.WindowsDesktop.App #353

Nefarion opened this issue Dec 2, 2021 · 29 comments

Comments

@Nefarion
Copy link

Nefarion commented Dec 2, 2021

Type of issue

[ ] Bug
[ ] Question (e.g. about handling/usage)
[x] Request for new feature/improvement

Expected Behavior

No targeting Microsoft.WindowsDesktop.App

Current Behavior

The v1.4.2 package adds a dependency to Microsoft.WindowsDesktop.App to projects targeting .net5.0-windows or .net6.0-windows.
Many AspNetCore applications run on windows servers that do not have the Microsoft.WindowsDesktop.App runtime/target installed, and thus do not start any more after upgrading to v1.4.2

Possible Solution (optional)

Isolate WPF functionality into a new package? It is only the XamlQRCode that requires the references to PresentationFramework/Microsoft.WindowsDesktop.App.

Your Environment

Version 1.4.2
TargetFramework: .net6.0-windows

@Nefarion
Copy link
Author

Nefarion commented Dec 2, 2021

Ah and please treat it as a suggestion, the simplest fix is of course to downgrade to 1.4.1 :)

@dylech30th
Copy link

This redundant reference will cause the ReSharper to break which will ruin the development experience, I hope it can be fixed so that I can upgrade the dependency

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

Hi @Nefarion ,

thanks for the suggestion. I had a look into your scenario and came to the conclusion, that I won't change the setup for now. (As long as you have no other arguments after you've read my following explanation.)

If I got you right, your problem is, that on Windows Server environments the Desktop related libraries (e.g. Microsoft.WindowsDesktop.App) aren't pre-installed and thus the application breaks in your case. Since you don't use XamlQRCode which needs this libraries, you expect QRCoder not to break. Correct?

For that specific QRCoder (and the NuGet package) contains multiple target frameworks. Besides other it also targets net5.0 and net5.0-windows. The DLL with target net5.0 does not include XamlQRCode and thus does not need the "missing" desktop libraries. Only the target net5.0-windows has this dependency.

So from my point of view, you are targeting the wrong framework in your application. If your environment does not have the desktop related libs available, then your application should target net5.0. In that case msbuild/VisualStudio would pick the net5.0 binary from the QRCoder package and everything would be fine.

Why do I say you picked the wrong target? Microsoft docs read out as follows:

.NET 5 introduced the net5.0-windows OS-specific TFM, which includes Windows-specific bindings for WinForms, WPF, and UWP APIs. .NET 6 introduces further OS-specific TFMs.
(source)

So picking net5.0-windows as target of your application you explicitly claim, that you need windows specific, additional libraries. And at the same time you complain that it comes to an error if an application wants to use them. Nevertheless, if you want to stay with net5.0-windows there's a workaround to keep this target and nevertheless use QRCoder 1.4.2.

So I see three possible solutions for your problem:

  1. Change the target of your application to from net5.0-windows to net5.0 (to reflect your runtime environment)
  2. Keep net5.0-windows as target, but install the necessary dependencies (or in other words install the full SDK or the .NET Desktop Runtime 5.0.12 instead of the smaller runtime bundles.)
  3. [Kind of workaround!] Keep net5.0-windows as target, but tell msbuild/VisualStudio explicitly to choose the ("Desktop dependency"-free) net5.0 binary of QRCoder. Therefore you have to manipulate your *.csproj as follows:
<!-- Find the package reference for QRCoder -->
<PackageReference Include="QRCoder" Version="1.4.2" />

<!-- Replace it with the following -->
<PackageReference Include="QRCoder" ExcludeAssets="Compile" Version="1.4.2" GeneratePathProperty="true" />
<Reference Include="QRCoder">
   <HintPath>$(PkgQRCoder)\lib\net5.0\QRCoder.dll</HintPath>
</Reference>

Explanation: By adding ExcludeAssets="Compile" we say that the compiler shouldn't take any DLL from the package. By adding GeneratePathProperty="true" we tell it to store the path to the package in a variable called PkgQRCoder.
Then we explicitly reference the QRCoder net5.0 version by given the full path in <HintPath>

Please let me know, if this solves your issues.

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

@dylech30th Can you please explain what you mean by "This redundant reference [...]". In how far there is a redundant reference? Furthermore please explain how this breaks ReSharper?

Can you please read the comment above I wrote for Nefarion and see if this is a solution for you, too? And if not, could you please open a new issue? For me it sounds like this may not directly be related to eachother.

@jnyrup
Copy link
Contributor

jnyrup commented Dec 3, 2021

To add some perspective, we have projects targeting net5.0-windows as they contain windows-only native dlls.
This helps us avoiding accidentally using windows-only dlls in linux applications.

As I read the quoted docs, targeting net5.0-windows only guarantees that some windows-only APIs used in WPF/WinForms are available.
This does not imply that targeting net5.0-windows guarantees that Microsoft.WindowsDesktop.App is available.

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

@jnyrup Correct, targeting net5.0-windows, doesn't guarantuee that Microsoft.WindowsDesktop.App is available.
But you could expect it to be available. When targeting net40 its also not guaranteed that .NET Framework 4.0 is installed on the host the application shall run on. That's task of the system owner/administrator. So if one targets net5.0-windows I would expect the admin to setup the runtime environment/server accordingly.

Nevertheless, if one doesn't want to use Windows related stuff, simply net5.0 should be targeted. In case Windows related libs shall be used net5.0-windows is the way to go, but then it must be ensured by the admin of the host which is running the application, that all runtimes in need are installed.

In case you want to use some Windows features, thus targeting your app net5.0-windows, but those features don't include Microsoft.WindowsDesktop.App and you do not want to use XamlQRCode, then simply use solution 3 from my above comment.

Or do I oversee something?

@Nefarion
Copy link
Author

Nefarion commented Dec 3, 2021

@codebude I totally forgot about Exclude and Include on Packages, thank you for the Workaround, i'll use it!

@Nefarion Nefarion closed this as completed Dec 3, 2021
@dylech30th
Copy link

My ReSharper reports ambiguous references in the XAML file on my WinUI 3 project (says it cannot choose between Microsoft.UI.Xaml.Controls.* and System.Windows.Controls.*, where the latter one belongs to the WPF and is not supposed to be referenced in a WinUI 3 project), and after I degrade the version of QRCoder to 1.4.1 the problem disappears, I've confirmed that this issue is neither caused by the .NET nor by the relative package references such as WindowsAppSDK or WinUI, as you can see in the following screenshots, add namespaces (xmlns:muxc="using:Microsoft.UI.Xaml.Controls") explicitly solves the reference resolution but the markup extensions such as StaticResource still appears to be broken.
RHA$8J3{@`SPSTW%ONHA659
6ATOS)6TFF{S(@8I~)@U6NL

And I've also assured that it's not ReSharper's problem as a new WinUI 3 project without any package reference works correctly, I've updated my NuGet package one by one and found the problem happens in this library, you can clone my project, update QRCoder to 1.4.2 and try to build solution in the following environment(even though I suspect that the problem will also raise in R# 2021.2 and VS 2019), the solution will be built successfully, but ReSharper will then report false positive (?) ambiguities in XAML file like the one's I've posted above.

My Environment:
My ReSharper version: 2021.3 EAP10 (the beta version)
Visual Studio version: 17.0.2
.NET version: This problem happens on both 5.0 and 6.0

After comparing the dependencies of 1.4.1 and 1.4.2 I've found that 1.4.2 is targeting SDK net5.0-windows7.0 which (presumably) is the reason for such problems, ReSharper may have automatically imported both namespaces when the DLL file is present

@jnyrup
Copy link
Contributor

jnyrup commented Dec 3, 2021

@codebude solution 3 works for me, I thought I had already tried it, but I must have failed to recompile properly.
So no bug per se for me, only microscopic unfortunate that I need to workaround it.

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

@dylech30th In QRCoder 1.4.1 there was no target for net5.0/net6.0. So in that case if you target your application to net5.0 the "nearest" target framework from the NuGet package is picked. That should have been netstandard2.0 for QRCoder 1.4.1. The netstandard2.0 target did not contain XamlQRCode (because desktop components weren't available for this target). Thus you see no errors when picking QRCoder 1.4.1.
From 1.4.2 on there are two new targets in QRCoder: net5.0 and net5.0-windows. The former one does not contain XamlQRCode (and behaves similar to netstandard2.0), the latter one does. So when using QRCoder 1.4.2 one of those two target binaries is picked up instead of netstandard2.0, because they are nearest to the target you chose for your application.

Same story as for @Nefarion - I suppose you to either target your app to net5.0 or use solution 3 from the comment above.

Alternatively use using-statements with aliases and prefix the calls. e.g.:

using UI = Microsoft.UI.Xaml.Controls;
using SW = System.Windows.Controls;
// Then use either UI.DataTemplate or SW.DataTemplate ...

In addition I think this isn't the fault of QRCoder. Libraries that target net5.0-windows are "allowed" to use WPF/System.Windows.Controls. So technically seen QRCoder is compliant to the spec. If using a compliant library in a WinUI3 project breaks ReSharper/VS than I guess it's something that should be sorted out by them?

@dylech30th
Copy link

I suppose so, sadly solution 3 didn't solve my problem (I've already modified the path to reveal the correct location by changing net5.0 to net6.0-windows10.0.19041.0, which is the TFM of my project), but since the build process works correct, It should be the ReSharper's duty to choose the right namespace to import depending on the project type.

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

@dylech30th net6.0-windows10.0.19041.0 is again -windows. QRCoder doesn't contain a net6.0 binary. Thus the nearest match is picked, which will be net5.0-windows which again will bring you trouble. So please try solution three and use net5.0 (without -windows) in the HintPath.

Alternatively try to use using-aliases as shown one comment above. ;-)

@dylech30th
Copy link

if I do exactly as solution 3 says the build will fail with the message:

Payload contains two or more files with the same destination path 'QRCoder.dll'. Source files: 
C:\Users\26532\.nuget\packages\qrcoder\1.4.2\lib\net5.0\QRCoder.dll
C:\Users\26532\.nuget\packages\qrcoder\1.4.2\lib\net5.0-windows7.0\QRCoder.dll

and I've also tried using-aliases, however, it won't work for the binding expression(x:Bind) and the markup extensions(such as StaticResource)

@codebude
Copy link
Owner

codebude commented Dec 3, 2021

Hi @dylech30th ,

The error Payload contains two or more files with the same destination path might have different sources. Please try to check the following points:

  • You have only one <PackageReference> and one <Reference> pointing to QRCoder. (Check that there is not a second PackageReference/Reference pointing to QRCoder. Only one for each as described in solution 3.
  • Restart Visual Studio
  • Refresh your NuGet package cache as described here and here.

@dylech30th
Copy link

Sorry none of them works...the problem is still there after I've purged the cache, and the PackageReference and Reference is confirmed to be only one for each

@codebude
Copy link
Owner

codebude commented Dec 4, 2021

Can you open a ticket at Jetbrains/Resharpen?

@dylech30th
Copy link

Ummm, I mean the build failure still exists (Payload contains two or more files with the same destination path), and if the build succeeded the problem may disappear. So I think this need to be solved first

@codebude
Copy link
Owner

codebude commented Dec 4, 2021

Hi @dylech30th ,

I still don't see what should be wrong. Are you sure that this isn't a problem/bug with ReSharper or your development environment?

I just forked your app and checked out the current master branch. I opened the solution in Visual Studio 2022 (17.0.0 Preview 7.0). Then I changed the QRCoder reference to 1.4.2 via NuGet package manager. After that I tried to build the solution. No build errors and no error in the error list were shown:

image

A quick run-tests/debugging session also worked without problems:
image

So I don't see what should be wrong with QRCoder.

@Nefarion
Copy link
Author

Nefarion commented Dec 6, 2021

Sorry to backtrack on this...
I tried the Solution 3), but it does not remove the dependency to Microsoft.WindowsDesktop.App. The dependency is added by nuget via the packageReference, not by using the dll. I can specify Exclude="All" and it still does it.
My solution right now is to downgrade to 1.4.1

@codebude
Copy link
Owner

codebude commented Dec 6, 2021

@Nefarion Is your solution publicly available? I would like to fiddle around to see what's wrong or can you setup a minimal project/solution to show what's wrong? I tried it myself, but couldn't reproduce your problem.

What i did:

  • I created a minimal app, targeting net5.0-windows
  • Added QRCoder 1.4.2 --> It broke
  • Added "workaround 3" --> It worked

I really would like to understand what's going on and why it isn't working for you.

@dylech30th
Copy link

@codebude Ummm that's weird because it seems that it will fail on my machine, I'll try to figure it out to see if it's due to my environment or the ReSharper.

@Nefarion
Copy link
Author

Nefarion commented Dec 6, 2021

@codebude
Repo is here: https://github.com/Nefarion/QRCoderProblem

dotnet publish -c Debug will create the net6.0 version,
dotnet publish -c Release will create the net6.0-windows version with your workaround,

if you look at the respective <publishdir>\QRCoderProblem.runtimeconfig.json, even with the workaround it still contains the reference to Microsoft.WindowsDesktop.App, and thus will always crash on startup with
something along the lines of "Required frameworks not installed"

Thank you for taking the time!

@codebude codebude reopened this Dec 7, 2021
@codebude
Copy link
Owner

codebude commented Dec 7, 2021

Since it seems to make more trouble than expected, I'll decouple XamlQRCode and QRCoder and also add net6.0 and net6.0-windows as targets. (This should solve the problems due to removal of the problematic dependencies from QRCoder.)
I'll update this issue as soon as the decoupling happened.

@codebude
Copy link
Owner

codebude commented Dec 9, 2021

Hi @jnyrup , @Nefarion , @dylech30th ,

I decoupled XamlQRCode (and its Windows-dependencies) from QRCoder and put it into a seperate package. Before public release on NuGet, I would like to get some feedback. (Do the changes solve your problems?)

Can you please take the latest CI-build and check if it's working for you? CI-Build Packages

If you need help on how to use Github Packages as NuGet package source, let me know (or check this article).

@jnyrup
Copy link
Contributor

jnyrup commented Dec 9, 2021

I just tried out the 1.4.3-preview and it solves the problem I had.
Thanks!

@codebude
Copy link
Owner

codebude commented Dec 9, 2021

@jnyrup that sounds great! If one or two more positive feedbacks show up (the changes also should solve #354 and #356 ) I'll push the new release to NuGet.

@Nefarion
Copy link
Author

Version 1.4.3-ci-20211209065116 also solves my problem!
Thanks!

@dylech30th
Copy link

My problem is solved using the preview version, thanks for your efforts!

@codebude
Copy link
Owner

Thanks for your help, testing and patience. QRCoder 1.4.3 was released right now: https://www.nuget.org/packages/QRCoder/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants