Skip to content

Multiple ClickOnce versions fail to be signed #760

Open

Description

Describe the bug

When using a git repository to host a ClickOnce project, additional previous versions may exist. This means each version will contain a manifest file so when the sign tool iterates through the ClickOnceSigner looking for a SingleOrDefault manifest to sign, it may find more than one, resulting in the below stack trace.

Repro steps

  1. Publish ClickOnce output
  2. Bump version
  3. Publish ClickOnce output to same directory
  4. Run sign tool on manifest .application file
  5. Profit Encounter exception

Expected behavior

I believe two different behaviors are acceptable here per manifest file:

  1. Iterate across all files, signing as usual.
  2. Iterate across all files. If files were previously signed, for example version 1 was signed previously, don't re-sign.

I believe the preference should probably be with the first, but I'm indifferent

Actual behavior

fail: Sign.Core.ISigner[0]
      Sequence contains more than one matching element
      System.InvalidOperationException: Sequence contains more than one matching element
         at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
         at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
         at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
         at Sign.Core.ClickOnceSigner.<>c__DisplayClass9_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 130
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.ClickOnceSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 82
         at Sign.Core.AggregatingSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/AggregatingSigner.cs:line 204
         at Sign.Core.Signer.<>c__DisplayClass3_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/Signer.cs:line 155
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.Signer.SignAsync(IReadOnlyList`1 inputFiles, String outputFile, FileInfo fileList, DirectoryInfo baseDirectory, String applicationName, String publisherName, String description, Uri descriptionUrl, Uri timestampUrl, Int32 maxConcurrency, HashAlgorithmName fileHashAlgorithm, HashAlgorithmName timestampHashAlgorithm) in /_/src/Sign.Core/Signer.cs:line 84

Additional context

Potentially problematic code:

// at this point contentFiles has all deploy files renamed
// Inner files are now signed
// now look for the manifest file and sign that if we have one
FileInfo? manifestFile = filteredFiles.SingleOrDefault(f => ".manifest".Equals(f.Extension, StringComparison.OrdinalIgnoreCase));
string fileArgs = $@"-update ""{manifestFile}"" {args}";

This issue happened with at least the three latest versions:

  • 0.9.1-beta.24406.1+6584f5d081d8a06660d58d1a777b2352ff376a68
  • 0.9.1-beta.24170.3
  • 0.9.1-beta.24361.2
dotnet --info
.NET SDK:
 Version:           8.0.400
 Commit:            36fe6dda56
 Workload version:  8.0.400-manifests.56cd0383
 MSBuild version:   17.11.3+0c8610977

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.400\

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
 [android]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    34.0.113/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.113\WorkloadManifest.json
   Install Type:        FileBased

 [maccatalyst]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    17.5.8020/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.5.8020\WorkloadManifest.json
   Install Type:        FileBased

 [wasm-tools]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.0.8/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.workload.mono.toolchain.current\8.0.8\WorkloadManifest.json
   Install Type:        FileBased

 [maui-windows]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.0.72/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.72\WorkloadManifest.json
   Install Type:        FileBased

 [ios]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    17.5.8020/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.5.8020\WorkloadManifest.json
   Install Type:        FileBased

 [aspire]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.1.0/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.1.0\WorkloadManifest.json
   Install Type:        FileBased


Host:
  Version:      8.0.8
  Architecture: x64
  Commit:       08338fcaa5

.NET SDKs installed:
  3.1.426 [C:\Program Files\dotnet\sdk]
  6.0.321 [C:\Program Files\dotnet\sdk]
  8.0.400 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Priority:1Work that is critical for the release, but we could probably ship withoutbug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions