perfview
perfview copied to clipboard
COM Interop assemblies are incorrectly packaged in Microsoft.Diagnostics.Tracing.TraceEvent
I spent some time earlier today trying to publish our dotnet diagnostic CLI tools as single-file exes, but in the process ended up discovering some oddities around how native assets are included in Microsoft.Diagnostics.Tracing.TraceEvent.
I’ve specifically ran into an issue with how Dia2Lib.dll, OSExtensions.dll, and TraceReLoggerLib.dll are included the NuGet package.
The issue I ran into was that these properties by virtue of being included via a NuGet package end up being included in the published output. Normally this is just benign as it overwrites existing files. In my case, the default NuGet targets resulted in $(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard2.0\Dia2Lib.dll being replaced by $(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\Dia2Lib.dll.
However, this breaks in the case of single-file publishes as we end up with multiple entries with the same BundleRelativePath.
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018: The "GenerateBundle" task failed unexpectedly. [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018: System.ArgumentException: Invalid input specification: Found multiple entries with the same BundleRelativePath [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018:
at Microsoft.NET.HostModel.Bundle.Bundler.GenerateBundle(IReadOnlyList`1 fileSpecs) [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018:
at Microsoft.NET.Build.Tasks.GenerateBundle.ExecuteCore() in /_/src/Tasks/Microsoft.NET.Build.Tasks/GenerateBundle.cs:line 36 [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018:
at Microsoft.NET.Build.Tasks.TaskBase.Execute() in /_/src/Tasks/Common/TaskBase.cs:line 38 [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018:
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [D:\temp\singlefilerepro\singlefilerepro.csproj]
C:\Program Files\dotnet\sdk\3.0.100-preview9-014004\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(809,5): error MSB4018:
at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [D:\temp\singlefilerepro\singlefilerepro.csproj]
Based on discussion here, it looks like the recommended fix is to handling deduping Microsoft.Diagnostics.Tracing.TraceEvent itself as opposed to relying on the SDK.
Here's a sample .csproj that reproes this issue when I run dotnet publish -r win-x64 /p:PublishSingleFile=true
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.45" GeneratePathProperty="true" />
</ItemGroup>
</Project>
and here's the rather inelegant workaround
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.45" GeneratePathProperty="true" />
</ItemGroup>
<Target Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle" Name="RemoveDupeAssemblies">
<ItemGroup>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\Dia2Lib.dll" />
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\OSExtensions.dll" />
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\TraceReloggerLib.dll" />
</ItemGroup>
</Target>
</Project>
@brianrob @noahfalk
@shirhatti Many thanks for the workaround, though it didn't work for me in the exact way you posted. I had to add the following additional lines as other native assemblies also had a bundle duplicates problem:
<Project Sdk="Microsoft.NET.Sdk">
...
<Target Name="Microsoft_Diagnostics_Tracing_TraceEvent_FIX_PublishSingleFile" Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle">
<ItemGroup>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\Dia2Lib.dll" />
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\OSExtensions.dll" />
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\netstandard1.6\TraceReloggerLib.dll" />
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\KernelTraceControl.dll" />
<_FilesToBundle Include="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\KernelTraceControl.dll">
<RelativePath>.\x86\KernelTraceControl.dll</RelativePath>
</_FilesToBundle>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\KernelTraceControl.Win61.dll" />
<_FilesToBundle Include="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\KernelTraceControl.Win61.dll">
<RelativePath>.\x86\KernelTraceControl.Win61.dll</RelativePath>
</_FilesToBundle>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\msdia140.dll" />
<_FilesToBundle Include="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\x86\msdia140.dll">
<RelativePath>.\x86\msdia140.dll</RelativePath>
</_FilesToBundle>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\amd64\KernelTraceControl.dll" />
<_FilesToBundle Include="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\amd64\KernelTraceControl.dll">
<RelativePath>.\amd64\KernelTraceControl.dll</RelativePath>
</_FilesToBundle>
<_FilesToBundle Remove="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\amd64\msdia140.dll" />
<_FilesToBundle Include="$(PkgMicrosoft_Diagnostics_Tracing_TraceEvent)\lib\native\amd64\msdia140.dll">
<RelativePath>.\amd64\msdia140.dll</RelativePath>
</_FilesToBundle>
</ItemGroup>
</Target>
Hopefully the authors will fix this properly soon.
Still seems to be an issue with Microsoft.Diagnostics.Tracing.TraceEvent 2.0.48
Same issue here on .NET 5. @shirhatti workaround fixed the problem for me.
@shirhatti, is there guidance on the right way to address this?
My naïve guess would be to use the Architecutre-specific support in NuGet- https://docs.microsoft.com/en-us/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders
Though I do believe that this is only supported in .NET Fx 4.6 and above which means you might have to preserve the custom MSBuild targets for older TFMs
Tried both suggested workarounds by @shirhatti and @jasmh but no luck. Targeting net5.0, win-x64, selfcontained and get the following error.
6>The "GenerateBundle" task failed unexpectedly.
6>System.ArgumentException: Invalid input specification: Found multiple entries with the same BundleRelativePath
Tried both suggested workarounds by @shirhatti and @jasmh but no luck. Targeting net5.0, win-x64, selfcontained and get the following error.
6>The "GenerateBundle" task failed unexpectedly. 6>System.ArgumentException: Invalid input specification: Found multiple entries with the same BundleRelativePath
I take it back! the property GeneratePathProperty="true" is what does the trick on the package reference for TraceEvent
Hello!
With VS 2022, publishing an application using this nuget package to a single exe is now broken. The application will not start, and the following is shown in the windows event log. This is a critical issue. I have tried version2.0.77 all the way up to the v3 version.
Description: A .NET application failed.
Application: ***.exe
Path: C:\......App.exe
Message: Error:
An assembly specified in the application dependencies manifest (....deps.json) was not found:
package: 'Microsoft.Diagnostics.Tracing.TraceEvent', version: '2.0.77'
path: 'lib/netstandard2.0/Dia2Lib.dll'
@aaronhudon just trying to understand the details here - are all the necessary files present if you don't publish as SingleFile? Would you be able to put together a minimal repro? I have used TraceEvent in SingleFile deployments successfully, so I'd like to make sure that I can fully understand what's happening here.
@brianrob yes, without the single exe option, publishing is fine.
This is a recent breaking change, not related to this package. I believe something has changed with msbuild, as we've noticed it when publishing using a devops agent. Hopefully something can be figured out, the single exe option is extremely helpful for my organization.