-
Notifications
You must be signed in to change notification settings - Fork 247
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
Bug: Version mismatch #1440
Comments
I believe it's probably falling back to the version included in the Windows SDK, VS doesn't include its own cppwinrt headers. The error generated by the |
@sylveon I'll start using the pragma you mentioned. You are correct that VS itself does not have its own cppwinrt header, rather it installs a version in the Program Files X86 under the Windows Kits, selected by the user or uses the defaults of VS installer. What it does seem to do is maintain somewhere a default reference to at least what was installed by the VS installer. This is likely because it is the only one VS could "know" about. This naturally would not prevent the developer from removing it - that is another can of worms. Nor does it prevent the developer from installing other versions of cppwinrt or using vcpkg or nuget. That is the problem effectively that I had, is a mismatch between the different sources one of which was the VS default fall back version which I did not know about. I was not aware that cppWinRT was included in the Windows SDK nor was I aware that VS "automatically" created references to cppWinRT. Automatic, is really the built-in links to the Windows SDK. While id does not matter to me now, I still don't know why VS fell back to a much earlier version unless it uses the minimum target platform specified rather than the target platform version select. I typically use the setting for "latest installed version" rather than a specific SDK. If this is the behavior to fall back to minimum, then using latest really isn't much value. |
The pragma is what C++/WinRT uses to generate the error, using it yourself won't do much benefit. The Windows Kits folder is where the Windows SDK gets installed. What is happening here is that VS by default adds the folders from the Windows SDK to the include order, and the SDK contains an outdated copy of C++/WinRT headers (even the latest Windows SDK does). When you install the C++/WinRT NuGet, it adds its own set of headers higher in the include order. |
I think @sylveon is right. The Windows SDK includes a bunch of cppwinrt generated headers and the version of cppwinrt used to generate those headers is always going to be older than the latest cppwinrt. Often a lot older. I believe the appropriate fix here is to ensure that the include directories are ordered such that the cppwinrt generated outputs local to your project are always used before the versions in the Windows SDK. That will ensure that the pragma mismatch is satisfied because all generated headers have the exact same version of cppwinrt. My understanding is that the project templates have the correct include ordering by default. |
The NuGet itself ensures it is in the right place in the include order. "Uses cppwinrt without declaring a version" suggests to me they were mixing projects where the NuGet was installed and others where it wasn't. |
In this case the "they" who is using mixed versions is me. I clearly did not understand how VS "decides" how to order things. I also didn't know that in the absence of a specific declaration that it used the Windows SDK, which happens to be listed first in the includes list. |
It is not a requirement that all DLLs within a single process must use the same version of cppwinrt. Rather, all of the translation units combining into a binary (DLL) must agree on the cppwinrt version. The primary purpose of cppwinrt is to take WinRT API definitions, in the form of a .winmd file, and project them into C++ headers so that C++ code can call WinRT APIs. As long as each DLL is self-consitent about the cppwinrt version and produces its own projects from winmd files then it will match and be fine. The trouble is when versions are crossed. |
Yes, mixing TUs with different versions risks running into ODR issues. |
Sometimes just finding the edges is the hardest part. |
Version
2.0.240405.15
Summary
This issue produces error that seem to point to CppWinRT and in fact the VS team said it is a CppWinRT issue. I am making a note here for those who might have a reported mismatch with some version of CppWinRT that you don't recall installing.
Visual Studio Installer installs a default version of CppWinRT that is a version that is in their build chain for a particular release. That is the default fallback version used no matter what you may specify as the Windows SDK version for your project. The VS behavior of falling back happens when some project that uses CppWinRT without explicitly declaring a version.
In my case this did not become apparent until I switched a project from a static to a dynamic version for my project. The VS documentation states that it automatically uses CppWinRT but fails to state that it is the install version in spite of the fact that you may subsequently install the correct version on your dev computer. This install is not an update it is a side-by-side additional version, VS continues to use the one defined it its original install.
The solution is to explicitly define the version and propagate that across all your projects that call that code. This may require a new feature branch in your source control, that is a normal problem we must deal with.
You can add the version to your package.config or edit the vcproj file with the matching version.
Reproducible example
#include <winrt/base.h>
#using <winrt/WindowsFoundation>
// if you have other projects that reference this project and in the other projects you specify cppWinRT and a version, // you must ensure that all use the same version.
Expected behavior
Since VS has a default property for WinRT, it should have at least a value for the resolved WinRT version in the General section of the properties to allow developers to see the version. If the developer selects a Vcpkg or a Nuget that has a version. VS should use the resolved value property to indicate a mismatch and list the values of all referenced projects. This would have save me a few days of work searching and CoPiloting.
Actual behavior
Output Window shows error in a WinRT mismatch and the version of the installed VS WinRT. Developer has no way to verify where this version comes from.
Additional comments
This clearly falls into the category VS blogs talk about as quality of life improvements.
The text was updated successfully, but these errors were encountered: