`SignFile` task using dotnet cli tries to use `signtool.exe` from wrong location
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
### Issue Description
Thanks to issue #6098, the `SignFile` task is now enabled in `dotnet msbuild` 16.11.
However, it does not actually seem to work.
I was under the impression that `SignFile` did the signing itself, using core framework functionality.; however, it turns out it wants to use `signtool.exe`, but does not actually locate it correctly.
So when using `SignFile` as part of `dotnet build`, I get:
```txt
error MSB3482: An error occurred while signing: SignTool.exe was not found at path xxx\signtool.exe.
```
where xxx is the project directory. When building a solution it wants `signtool.exe` to be present in every project's directory separately.
MSBuild should be able to locate it properly; I had my own lookup in place before, using
```xml
$(WindowsSdkVerBinPath)x64\signtool.exe
$(WindowsSdkVerBinPath)x86\signtool.exe
$(WindowsSdkVerBinPath)x86\signtool.exe
```
and that would have led to using `C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe` just fine.
### Steps to Reproduce
- create a simple project:
```pwsh
dotnet new classlib -n CodeSigning
cd CodeSigning
```
- generate a self-signed certificate
```pwsh
New-SelfSignedCertificate -Type CodeSigningCert -Subject CN=CodeSigning -CertStoreLocation Cert:\CurrentUser\My
```
This will produce output like:
```txt
PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My
Thumbprint Subject EnhancedKeyUsageList
---------- ------- --------------------
B77064C7175EF732F534B8D28C337CA2FB87E9D2 CN=CodeSigning Code Signing
```
make a note of that thumbprint value; it's needed in the next step.
- Set up code signing in the project by adding this target to CodeSigning.csproj:
```xml
B77064C7175EF732F534B8D28C337CA2FB87E9D2
<_AssembliesToSign Include="$(IntermediateOutputPath)$(TargetFileName)" />
<_AssembliesToSign Include="@(IntermediateSatelliteAssembliesWithTargetPath)" />
<_AssembliesToSign Include="@(RazorIntermediateAssembly)" />
```
making sure that the value of `$(SigningCertificate)` is the thumbprint of the certificate you generated.
- build using `msbuild`; this should succeed, with output including
```txt
_SignAssemblies:
Signing assemblies: obj\Debug\net5.0\CodeSigning.dll
CopyFilesToOutputDirectory:
```
- build using `dotnet build -v:n`; this will fail with an error like
```txt
_SignAssemblies:
Signing assemblies: obj\Debug\net5.0\CodeSigning.dll
1>...\CodeSigning\CodeSigning.csproj(17,5): error MSB3482: An error occurred while signing: SignTool.exe was not found at path ...\CodeSigning\signtool.exe.
```
### Expected Behavior
The `SignFile` task works, signing the assemblies, when using either `dotnet build` or `msbuild`.
### Actual Behavior
The `SignFile` task works only when using `msbuild`.
### Analysis
The `SignFile` task implementation does not seem to locate SignTool correctly when using `dotnet build`.
(And in addition, I thought that it was doing the signing itself (which would potentially make it work on Linux as well, which would be very convenient for CI/CD scenarios), using corefx functionality, not using an external utility from a Windows Kit.)
### Versions & Configurations
Tested using VS2019 16.11.2 and .NET SDK 5.0.400, i.e. MSBuild 16.11.0.36601 on x64 Windows.
I'm not sure how to set up a certificate on Linux (no `New-SelfSignedCertificate` in `pwsh` there), but that would only matter if `SignFile` did the signing itself and not via SignTool.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.