-
Notifications
You must be signed in to change notification settings - Fork 342
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
Using a C++WinRT component in C# project error CS0400: The type or namespace name could not be found in the global namespace (are you missing an assembly reference?) #5071
Comments
Wouldn't this be a .NET issue? Older versions of .NET Core and .NET Framework could read the .winmd files directly. However, .NET 5 removed this support. This is an issue independent of the Windows App SDK because if you start off with a WPF application and then reference a C++ library implemented as a WinRT component created using the Windows Runtime Component (C++/WinRT) template then the exact same thing will happen. The only reason why this isn't a more general problem is because the Windows SDK references are satisfied using the CsWinRT projection provided by the Microsoft.Windows.SDK.NET.Ref NuGet package and the WinUI 3 references are satisfied by the projection provided by the Windows App SDK NuGet package. Really, the best way for this to be fixed is if the .NET SDK automatically generates a CsWinRT projection if it detects a .winmd reference. The best option is for you to create a CsWinRT projection and then reference that from the .NET application. |
@DarranRowe I am relatively new to C# and honestly don't understand what you are saying. I hope there is a complete documentation about this, that works |
@HO-COOH As a quick and dirty example, I created and uploaded this project. I kind of used the Generate a C# projection from a C++/WinRT component walkthrough. But I used my own C++/WinRT component. I also completely ignored the create a NuGet package step and directly referenced the projection DLL from the console application. Another thing to note is that because the application is unpackaged, I used Registration Free WinRT to reference the C++ WinRT component. This is in the app.manifest file. The only unexpected thing that I needed to do was to also add the CsWinRT in the console application. If I didn't do this then I would get a NETSDK1130 error. The package reference being transitive isn't good enough. But for full disclosure, I barely use C#, and this was the very first time I have done something like this. I just have a pretty good understanding of how things work on the C++ side and just had a pretty good guess at CsWinRT taking up the same role as CppWinRT. |
@DarranRowe Can you explain how did you make your |
That started as a regular C# Class Library project. It did require manual editing of the project file.
Save and then close the tab. That should be all that is needed. |
@HO-COOH , Was DarrenRowes comment helpful for you? |
No, actually. He/She is using Registration Free WinRT, which is not my use case. You should really provide a documenttion, like this one. Also, C++WinRT is already gone from the |
The only reason why I am using RegFreeWinRT is because I was showing it off properly in an unpackaged application. I think I already stated that I am still relatively inexperienced in C#, so I was unsure of what was needed and what wasn't. But apparently the RegFreeWinRT registration isn't even needed. I would guess that CsWinRT is bypassing RoActivateInstance, but I couldn't assume that. But in general, the only thing that the registration would affect is how the component is activated. This, in my mind, means that it is outside of the scope of this issue this issue is about getting the application to build. If the application is packaged then it would be registered in the package manifest normally. I didn't mention this since I thought this was obvious to UWP developers. Also, the documentation that you state "You should really provide documentation" like also uses RegFreeWinRT. It would also be the CsWinRT team that is responsible for the documentation. Also, as an interesting sidenote, there are ways to sidestep the requirement for RegFreeWinRT here. C++/WinRT looks for components based upon file name and it is possible to rename WinRT.Host.dll. So it is easy enough to not know how the component is registered, and in this case you should have asked if there were other ways of discovering the component without using RegFreeWinRT. |
(Components') Activation is part of COM. And Thus, RegFreeWinRT is a mandatory requirement from COM. If any of the "Language Projections" are bypassing RegFreeWinRT, then they are not following up COM's requirements in the first place. |
@DarranRowe Your console application crash on exit. And I still couldn't get it working. Would appreciate if you can do the same for a packaged winui3 C# project. |
2025-02-02.22-45-53.mp42025-02-02.22-51-20.mp4I disagree with this statement. I will not deny that my system is showing a non critical Windows Error Reporting entry in the Event Viewer, but that is why I recorded the desktop, clock included. The timestamp on that report is 22:44, and the clock shows 22:45 and 22:51 when I was running the test application in the various platform/configuration pairs. I will put together a sample for WinUI 3, but it will take a few days. It is currently late on Sunday, and I am busy during the week. Although for a packaged application, it is registered as a package extension. The example in the package schema reference is what you should be aiming for. |
Well, I will put the project on GitHub later, but as I stated, the only relevant difference was the component had to be registered in the package manifest. The following is the project's Package.appxmanifest file.
The registration in Extensions is what mirrors RegFreeWinRT. Custom XAML controls are just an extension of this, you just have to remember to register all of the runtime classes, including the metadata provider. If you ever get stuck not knowing what names to register, just remember that the C++ component's .winmd file can be opened with ildasm. This gets installed as part of the Windows SDK. Anyway, if you place the fully qualified name of any activatable or composable runtime classes into the package manifest then it will be properly registered. It is possible to use the projection, but it contains a lot of extra things which can be confusing. |
The project can be found here. |
@DarranRowe <Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TestComponent.dll</Path>
<ActivatableClass ActivatableClassId="TestComponent.Class" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions> is not needed, and the project can still install and run fine. |
It is technically needed for it to be correct. As I stated previously, it seems like the C# projection is bypassing RoActivateInstance. Since the library the component is in is named after the namespace, the C# projection is able to remove the runtime class name from the end and start looking for libraries named after all or part of the namespace that the runtime class is in. C++/WinRT does this too. So the way to look at it is if the runtime class' fully qualified name is something like The RoActivateInstance call requires the registration, and there are a couple of cases where it can fall back to RoActivateInstance unexpectedly. So even if it isn't needed in these cases, it is always better to have the runtime classes registered in the package manifest. As an example, I took the sample that I provided but I added a second component to it. The library has the name
This means there is no link between the namespace and the library name. 2025-02-09.16-43-35.mp4This video shows what happens when there is an attempt to activate the component. I step into it using the debugger to make sure that the exception is properly shown in the debugger. This fails with a REGDB_E_CLASSNOTREG error. 2025-02-09.16-44-20.mp4This video shows what happens when the component is registered in the package manifest file. The component activates normally. If you wish, I will merge the changes and push them to the repository so you can see it in action yourself. --EDIT-- As a bit of an addition to this, especially if there was an attempt to replicate this using a C++/WinRT project, the packaging system does something interesting when there is a direct component dependency. The project system automatically makes a reference in the package to the component. In other words, the package extension is automatically filled in based upon the .winmd file. To see the difference, compare the Package.appxmanifest file to the output AppxManifest.xml file. Annoyingly/ironically, the easiest way of showing this in action is with registration free WinRT, since this is easier to set up in an unpackaged setting than using manual packaging. Anyway, to show this in action, I have the following two video files. 2025-02-11.17-00-14.mp4This shows what happens when the component is unregistered. I show that the registration is commented out in the manifest file. Since this was based upon the separate packaging project template, I also show that the application is being run directly by showing that the package layout has not been created or deployed. C++/WinRT loads the library successfully, but a direct call to RoActivateInstance fails. 2025-02-11.17-01-45.mp4This shows the registration in the manifest file being enabled. Again I show that the packaging project is not being used. This time, RoActivateInstance succeeds. In other words, the projections can bypass some of the inbuilt windows functionality. This may make it seem like some registrations are not needed. However these registrations are needed under the right circumstances. In the end, I only mention this because if things go wrong then you know how to debug things and are able to rectify the issue. If you control things enough that this never affects you then just ignore this. |
Describe the bug
After 5+ yrs of tooling development, it still does not work out of the box. This is kind of epic. (And UWP project using the same step does work out of the box, without needing to add the nuget)
What I did:
csproj
file has windows sdk version in<TargetFramework>
✅CsWinRT
nuget ✅Steps to reproduce the bug
Expected behavior
No response
Screenshots
No response
NuGet package version
Windows App SDK 1.6.3: 1.6.250108002
Packaging type
Packaged (MSIX)
Windows version
Windows 11 version 24H2 (22621, October 2024 Update)
IDE
Visual Studio 2022
Additional context
Repro
The text was updated successfully, but these errors were encountered: