Summary
The DLLs in the 2.80.0 packages (Grpc.Net.Client, Grpc.Net.ClientFactory, Grpc.Net.Common, Grpc.Core.Api) all ship with FileVersion = 2.66.0.0, which is lower than the same DLLs in 2.76.0 (FileVersion = 2.76.0.0). ProductVersion is correct in both releases — only the Win32 FileVersion resource regressed.
2.80.0-pre1 is affected the same way; 2.76.0 is fine.
Reproduction
Any platform with PowerShell can reproduce by inspecting the DLL inside the NuGet packages:
$tmp = New-Item -ItemType Directory -Force -Path "$env:TEMP\grpc-check"
foreach ($pkg in 'grpc.net.client','grpc.net.clientfactory','grpc.net.common','grpc.core.api') {
foreach ($v in '2.76.0','2.80.0') {
$nupkg = Join-Path $tmp "$pkg-$v.nupkg"
Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/$pkg/$v/$pkg.$v.nupkg" -OutFile $nupkg
$zip = [System.IO.Compression.ZipFile]::OpenRead($nupkg)
$entry = $zip.Entries | Where-Object { $_.FullName -match 'lib/net(8\.0|standard2\.[01])/[^/]+\.dll$' } | Select-Object -First 1
$dll = Join-Path $tmp "$pkg-$v.dll"
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $dll, $true)
$zip.Dispose()
$info = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($dll)
'{0,-25} {1,-7} -> FileVersion={2,-10} ProductVersion={3}' -f $pkg, $v, $info.FileVersion, $info.ProductVersion
}
}
Output:
grpc.core.api 2.76.0 -> FileVersion=2.76.0.0 ProductVersion=2.76.0+c52862d2…
grpc.core.api 2.80.0 -> FileVersion=2.66.0.0 ProductVersion=2.80.0+f22747c7…
grpc.net.client 2.76.0 -> FileVersion=2.76.0.0 ProductVersion=2.76.0+c52862d2…
grpc.net.client 2.80.0 -> FileVersion=2.66.0.0 ProductVersion=2.80.0+f22747c7…
grpc.net.clientfactory 2.76.0 -> FileVersion=2.76.0.0 ProductVersion=2.76.0+c52862d2…
grpc.net.clientfactory 2.80.0 -> FileVersion=2.66.0.0 ProductVersion=2.80.0+f22747c7…
grpc.net.common 2.76.0 -> FileVersion=2.76.0.0 ProductVersion=2.76.0+c52862d2…
grpc.net.common 2.80.0 -> FileVersion=2.66.0.0 ProductVersion=2.80.0+f22747c7…
All four 2.80.0 DLLs share the suffix f22747c7…, suggesting they came from a single CI run. The uniform 2.66.0.0 looks like a stale build variable that wasn't bumped along with the package version.
Real-world impact
This breaks Windows Installer (MSI) major upgrades for any product that ships these DLLs. MSI uses Win32 FileVersion (not ProductVersion) to decide whether to overwrite an existing file. When a customer is upgrading an installation that has the 2.76.0 DLLs on disk:
- File on disk:
FileVersion = 2.76.0.0
- Incoming MSI's payload:
FileVersion = 2.66.0.0
MSI logs "Disallowing installation of component … since the same component with higher versioned keyfile exists" during CostFinalize, skips installing the four DLLs, and then RemoveExistingProducts deletes the on-disk copies as part of removing the old product. End state: the four DLLs are missing post-upgrade, the application fails to start, and uninstall + reinstall is the only customer-side workaround.
Workaround
Pin to Grpc.Net.Client / Grpc.Net.ClientFactory / Grpc.Net.Common / Grpc.Core.Api 2.76.0. Hold off on 2.80.x until a release with FileVersion >= 2.76.0.0 is published.
Suggested fix
In the CI/build pipeline that produces these packages, ensure the FileVersion MSBuild property (or equivalent AssemblyFileVersion attribute) is derived from the same source as the NuGet package version, so a release tag bump propagates to the Win32 resource as well.
Summary
The DLLs in the
2.80.0packages (Grpc.Net.Client,Grpc.Net.ClientFactory,Grpc.Net.Common,Grpc.Core.Api) all ship withFileVersion = 2.66.0.0, which is lower than the same DLLs in2.76.0(FileVersion = 2.76.0.0).ProductVersionis correct in both releases — only the Win32FileVersionresource regressed.2.80.0-pre1is affected the same way;2.76.0is fine.Reproduction
Any platform with PowerShell can reproduce by inspecting the DLL inside the NuGet packages:
Output:
All four
2.80.0DLLs share the suffixf22747c7…, suggesting they came from a single CI run. The uniform2.66.0.0looks like a stale build variable that wasn't bumped along with the package version.Real-world impact
This breaks Windows Installer (MSI) major upgrades for any product that ships these DLLs. MSI uses Win32
FileVersion(notProductVersion) to decide whether to overwrite an existing file. When a customer is upgrading an installation that has the2.76.0DLLs on disk:FileVersion = 2.76.0.0FileVersion = 2.66.0.0MSI logs
"Disallowing installation of component … since the same component with higher versioned keyfile exists"duringCostFinalize, skips installing the four DLLs, and thenRemoveExistingProductsdeletes the on-disk copies as part of removing the old product. End state: the four DLLs are missing post-upgrade, the application fails to start, anduninstall + reinstallis the only customer-side workaround.Workaround
Pin to
Grpc.Net.Client/Grpc.Net.ClientFactory/Grpc.Net.Common/Grpc.Core.Api2.76.0. Hold off on2.80.xuntil a release withFileVersion >= 2.76.0.0is published.Suggested fix
In the CI/build pipeline that produces these packages, ensure the
FileVersionMSBuild property (or equivalentAssemblyFileVersionattribute) is derived from the same source as the NuGet package version, so a release tag bump propagates to the Win32 resource as well.