Closed emako closed 1 year ago
What is this publish operation? Is this dotnet publish -r win-x64
?
I'm not use CLI to publish.
My FolderProfile.pubxml file here, and publish by vs2022
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<PublishDir>bin\x64\Release\net6.0-windows10.0.18362.0\publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>false</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>
Under my testing, it will only happened when using Microsoft Visual Studio.
This will cause that I cannot generate MSIX packages through Visual Studio.
dotnet publish -r win-x64
or dotnet publish -p:PublishProfile=FolderProfile
will ok to build the x64 bin.
Microsoft Visual Studio Professional 2022 (64-bit) - Current Version 17.3.2 The newer VS2022 version has too mach bug to use, I using 17.3.2 nowaday.
This bug is very annoying and forces me to drop to the command line whenever I'm publishing builds. I can confirm it happens in VS 2019, too.
I'm not familiar with pubxml files and cannot guess the project type that you're trying to build. But given CLI builds/publish work for you, I daresay the bug isn't in CsWin32, but rather with the Visual Studio project system that you're trying to publish with. The bug should be filed with them. If you don't know how or where to file it, comment again on this issue (even after I close it) with a repro project and I'll find its owners and either forward the bug or tell you where you can file it.
WpfApp1.zip
This project reproduces the issue.
It uses only HWND
and cannot be published as win-x64
through FolderProfile.pubxml.
Thanks. I took a look and found one problem (but there are more):
The VS Publish command builds the project twice. The first time works, as it's apparently a standard build. But the second time is the Publish build, and it is doing something funky that breaks CsWin32. In particular, it invokes the compiler without /additionalfile:NativeMethods.txt
switch or the /unsafe+
switch. Both of these come from CsWin32's nuget package's msbuild files that are supposed to be imported by the project file, but evidently are not for the publish build.
By adding two elements to the project file, I was able to workaround that deficiency:
But it turned out there was more than that. The win32metadata package has its own msbuild import which was also being skipped. In the end, I was able to get a successful publish step by copying the whole content of both .props files into the project file itself, and then switch to an absolute path because the $(NuGetPackageRoot)
property wasn't set.
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Remove="NativeMethods.json" />
<None Remove="NativeMethods.txt" />
<AdditionalFiles Include="NativeMethods.json" Condition="Exists('NativeMethods.json')" />
<AdditionalFiles Include="NativeMethods.txt" Condition="Exists('NativeMethods.txt')" />
</ItemGroup>
<ItemGroup>
<!-- Provide the path to the winmds used as input into the analyzer. -->
<CompilerVisibleProperty Include="CsWin32InputMetadataPaths" />
<CompilerVisibleProperty Include="CsWin32InputDocPaths" />
</ItemGroup>
<Target Name="AssembleCsWin32InputPaths" BeforeTargets="GenerateMSBuildEditorConfigFileCore">
<!-- Roslyn only allows source generators to see msbuild properties, to lift msbuild items into semicolon-delimited properties. -->
<PropertyGroup>
<CsWin32InputMetadataPaths>@(ProjectionMetadataWinmd->'%(FullPath)','|')</CsWin32InputMetadataPaths>
<CsWin32InputDocPaths>@(ProjectionDocs->'%(FullPath)','|')</CsWin32InputDocPaths>
</PropertyGroup>
</Target>
<Target Name="FixMds" BeforeTargets="CoreCompile" Condition="'@(ProjectionMetadataWinmd)'==''">
<Message Importance="high" Text="Adding missing winmd" />
<ItemGroup>
<ProjectionMetadataWinmd Include="C:\.tools\.nuget\packages\microsoft.windows.sdk.win32metadata\55.0.45-preview\Windows.Win32.winmd" />
</ItemGroup>
</Target>
I think ultimately, the problem is just that: $(NuGetPackageRoot)
isn't set in a VS Publish build. That would explain the lack of imports. That needs to be fixed. But that's a VS product problem. Can you use Report a Problem in VS and share the link for what you create here? Feel free to link to that issue from the feedback ticket you create so they can see the research here.
Thanks. I took a look and found one problem (but there are more): The VS Publish command builds the project twice. The first time works, as it's apparently a standard build. But the second time is the Publish build, and it is doing something funky that breaks CsWin32. In particular, it invokes the compiler without
/additionalfile:NativeMethods.txt
switch or the/unsafe+
switch. Both of these come from CsWin32's nuget package's msbuild files that are supposed to be imported by the project file, but evidently are not for the publish build.By adding two elements to the project file, I was able to workaround that deficiency:
But it turned out there was more than that. The win32metadata package has its own msbuild import which was also being skipped. In the end, I was able to get a successful publish step by copying the whole content of both .props files into the project file itself, and then switch to an absolute path because the
$(NuGetPackageRoot)
property wasn't set.<PropertyGroup> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> <ItemGroup> <None Remove="NativeMethods.json" /> <None Remove="NativeMethods.txt" /> <AdditionalFiles Include="NativeMethods.json" Condition="Exists('NativeMethods.json')" /> <AdditionalFiles Include="NativeMethods.txt" Condition="Exists('NativeMethods.txt')" /> </ItemGroup> <ItemGroup> <!-- Provide the path to the winmds used as input into the analyzer. --> <CompilerVisibleProperty Include="CsWin32InputMetadataPaths" /> <CompilerVisibleProperty Include="CsWin32InputDocPaths" /> </ItemGroup> <Target Name="AssembleCsWin32InputPaths" BeforeTargets="GenerateMSBuildEditorConfigFileCore"> <!-- Roslyn only allows source generators to see msbuild properties, to lift msbuild items into semicolon-delimited properties. --> <PropertyGroup> <CsWin32InputMetadataPaths>@(ProjectionMetadataWinmd->'%(FullPath)','|')</CsWin32InputMetadataPaths> <CsWin32InputDocPaths>@(ProjectionDocs->'%(FullPath)','|')</CsWin32InputDocPaths> </PropertyGroup> </Target> <Target Name="FixMds" BeforeTargets="CoreCompile" Condition="'@(ProjectionMetadataWinmd)'==''"> <Message Importance="high" Text="Adding missing winmd" /> <ItemGroup> <ProjectionMetadataWinmd Include="C:\.tools\.nuget\packages\microsoft.windows.sdk.win32metadata\55.0.45-preview\Windows.Win32.winmd" /> </ItemGroup> </Target>
I think ultimately, the problem is just that:
$(NuGetPackageRoot)
isn't set in a VS Publish build. That would explain the lack of imports. That needs to be fixed. But that's a VS product problem. Can you use Report a Problem in VS and share the link for what you create here? Feel free to link to that issue from the feedback ticket you create so they can see the research here.
Thank you so much! The solution worked, and I'll also report it to VS soon.
Actual behavior
[A clear and concise description of what the bug is.]
Can not publish project when target runtime is
win-x64
, butPortable
is OK.Expected behavior
A clear and concise description of what you expected to happen.
Repro steps
NativeMethods.txt
content:NativeMethods.json
content (if present):Any of your own code that should be shared?
Context
0.2.138-beta
]net6.0
]LangVersion
(if explicitly set by project): [10.0
]