Skip to content

Commit 454b316

Browse files
committed
Update to version 2.1.0.0 with new features and fixes (dev / test current)
Updated CHANGELOG.MD to reflect version 2.1.0.0, highlighting improvements such as persisting Trusted Signing options, restoring the last "Files to Sign" list, and adding detailed diagnostics for Trusted Signing. Enhanced `MainForm.cs` to load and save Trusted Signing options and file lists between sessions, with robust error handling and logging. Improved `SignerTrustedSigning.cs` to log resolved absolute paths for better traceability and location of .dll´s. Improved logging and diagnostics across the codebase for better user feedback and troubleshooting.
1 parent 3341274 commit 454b316

8 files changed

Lines changed: 586 additions & 12 deletions

File tree

CHANGELOG.MD

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
## Version 2.0.0.0 (11-09-2025)
1+
## Version 2.1.0.0 (04-11-2025)
2+
3+
### 🔧 Improvements
4+
- Persist Trusted Signing options (Code Signing Account Name and Certificate Profile) between sessions
5+
- Restore last "Files to Sign" list on startup
6+
- Add detailed Trusted Signing diagnostics in logs:
7+
- Log exact SignTool arguments used for the call
8+
- Log resolved and better check for absolute paths for DLIB and DMDF and the current working directory
9+
10+
## Version 2.0.0.0 (11-09-2025)
211

312
### 🆕 New Features
413
- Added certificate monitoring functionality with new `CertificateMonitor` class and `CertificateStatus` Form

src/AI Setup Project/SignToolGUI Installer.aip

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<DOCUMENT Type="Advanced Installer" CreateVersion="21.9" version="23.1" PreviousModules="simple" Modules="professional" RootPath="." Language="en" Id="{C91F2B90-326D-4B52-99AE-6996B4FA77F1}">
2+
<DOCUMENT Type="Advanced Installer" CreateVersion="21.9" version="23.2" PreviousModules="simple" Modules="professional" RootPath="." Language="en" Id="{C91F2B90-326D-4B52-99AE-6996B4FA77F1}">
33
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
44
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
55
<ROW Property="AI_PROPPATH_DIR_PERBUILD_Azure.CodeSigning.Dlib.Core.dll" Value="..\SignToolGUI\bin\Release\Tools"/>
@@ -109,10 +109,10 @@
109109
<ROW Property="ALLUSERS" Value="1"/>
110110
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName] v. [|ProductVersion]" ValueLocId="*"/>
111111
<ROW Property="Manufacturer" Value="Michael Morten Sonne"/>
112-
<ROW Property="ProductCode" Value="1033:{540EE35F-296E-4010-821A-EA2FF8FD849E} " Type="16"/>
112+
<ROW Property="ProductCode" Value="1033:{6ECC2200-B6C0-4ADD-8BE8-ED3FEE8F2E44} " Type="16"/>
113113
<ROW Property="ProductLanguage" Value="1033"/>
114114
<ROW Property="ProductName" Value="SignToolGUI"/>
115-
<ROW Property="ProductVersion" Value="2.0.0.0" Options="32"/>
115+
<ROW Property="ProductVersion" Value="2.1.0.0" Options="32"/>
116116
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
117117
<ROW Property="UpgradeCode" Value="{6F8F60D8-0325-4FA9-B18A-9EE2702C1232}"/>
118118
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>

src/AI Setup Project/SignToolGUI Installer.back(23.1).aip

Lines changed: 436 additions & 0 deletions
Large diffs are not rendered by default.

src/SignToolGUI.sln

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 18
4-
VisualStudioVersion = 18.0.10828.68 main
4+
VisualStudioVersion = 18.0.10828.68
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignToolGUI", "SignToolGUI\SignToolGUI.csproj", "{5E3E0028-03EE-4FE0-9A52-4A5AE04B5E0B}"
77
EndProject
@@ -35,7 +35,6 @@ Global
3535
{EED69928-407C-4C65-89A8-56244E46764D}.All|Any CPU.ActiveCfg = DefaultBuild
3636
{EED69928-407C-4C65-89A8-56244E46764D}.All|Any CPU.Build.0 = DefaultBuild
3737
{EED69928-407C-4C65-89A8-56244E46764D}.Debug|Any CPU.ActiveCfg = DefaultBuild
38-
{EED69928-407C-4C65-89A8-56244E46764D}.Debug|Any CPU.Build.0 = DefaultBuild
3938
{EED69928-407C-4C65-89A8-56244E46764D}.DefaultBuild|Any CPU.ActiveCfg = DefaultBuild
4039
{EED69928-407C-4C65-89A8-56244E46764D}.DefaultBuild|Any CPU.Build.0 = DefaultBuild
4140
{EED69928-407C-4C65-89A8-56244E46764D}.Release|Any CPU.ActiveCfg = DefaultBuild

src/SignToolGUI/Class/SignerTrustedSigning.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.IO;
33
using System.Text.Json;
4+
using static SignToolGUI.Class.FileLogger;
45

56
namespace SignToolGUI.Class
67
{
@@ -98,9 +99,21 @@ protected override string BuildSigningArguments(string targetAssembly, string ti
9899
throw new InvalidOperationException($"Dmdf file not found at: {DmdfPath}");
99100
}
100101

102+
// Resolve absolute paths for logging
103+
string dlibFullPath = Path.GetFullPath(DlibPath);
104+
string dmdfFullPath = Path.GetFullPath(DmdfPath);
105+
string cwd = Directory.GetCurrentDirectory();
106+
101107
// For Trusted Signing, always use the fixed timestamp server
102108
// The timestampUrl parameter is ignored because Trusted Signing uses a fixed timestamp URL
103-
var arguments = $@"sign {GlobalOptionSwitches()} /fd sha256 /tr ""{_timestampServer}"" /td sha256 /dlib ""{DlibPath}"" /dmdf ""{DmdfPath}"" ""{targetAssembly}""";
109+
var arguments = $@"sign {GlobalOptionSwitches()} /fd sha256 /tr ""{_timestampServer}"" /td sha256 /dlib ""{dlibFullPath}"" /dmdf ""{dmdfFullPath}"" ""{targetAssembly}""";
110+
111+
// Keep exact call for traceability
112+
Message($"Calling Trusted Signing via arguments: '{arguments}'", EventType.Information, 3032);
113+
114+
// Log resolved locations for clarity
115+
Message($"Resolved DLIB location: '{dlibFullPath}'", EventType.Information, 3033);
116+
Message($"Resolved DMDF location: '{dmdfFullPath}' | Working directory: '{cwd}'", EventType.Information, 3033);
104117

105118
return arguments;
106119
}

src/SignToolGUI/Forms/ChangelogForm.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@ private void ChangelogForm_Load(object sender, EventArgs e)
1919
private void PopulateChangelog()
2020
{
2121
// Changelog content
22-
var changelogContent = " Version 2.0.0.0 (11-09-2025):\n\n" +
22+
var changelogContent =
23+
" Version 2.1.0.0 (04-11-2025):\n" +
24+
" Improvements\n" +
25+
" - Persist Trusted Signing options (Code Signing Account Name and Certificate Profile) between sessions\n" +
26+
" - Restore last 'Files to Sign' list on startup\n" +
27+
" - Add detailed Trusted Signing diagnostics in logs:\n" +
28+
" - Log exact SignTool arguments used for the call\n" +
29+
" - Log resolved and better check for absolute paths for DLIB and DMDF and the current working directory\n\n" +
30+
" Version 2.0.0.0 (11-09-2025):\n" +
2331
" New Features\n" +
2432
" - Added certificate monitoring functionality with new CertificateMonitor class and CertificateStatus Form\n" +
2533
" - Introduced comprehensive timestamp server management system\n" +

src/SignToolGUI/Forms/MainForm.cs

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,79 @@ private void MainForm_Load(object sender, EventArgs e)
322322
textBoxPFXPassword.Text = "";
323323
}
324324

325+
// Load last used Trusted Signing options
326+
try
327+
{
328+
var savedAccount = iniFile.GetString("TrustedSigning", "AccountName", "");
329+
if (!string.IsNullOrWhiteSpace(savedAccount))
330+
textBoxCodeSigningAccountName.Text = savedAccount;
331+
332+
var savedProfile = iniFile.GetString("TrustedSigning", "CertificateProfile", "");
333+
if (!string.IsNullOrWhiteSpace(savedProfile))
334+
textBoxCertificateProfileName.Text = savedProfile;
335+
}
336+
catch (Exception ex)
337+
{
338+
Message($"Error loading Trusted Signing options: {ex.Message}", EventType.Error, 3050);
339+
}
340+
341+
// Load last file list to sign
342+
try
343+
{
344+
var filesJson = iniFile.GetString("Files", "ToSign", "");
345+
if (!string.IsNullOrEmpty(filesJson))
346+
{
347+
// Prefer robust parse to handle both JSON array and single string fallback
348+
List<string> files = null;
349+
try
350+
{
351+
files = System.Text.Json.JsonSerializer.Deserialize<List<string>>(filesJson);
352+
}
353+
catch
354+
{
355+
// Try parse using JsonDocument in case of formatting issues
356+
using (var doc = System.Text.Json.JsonDocument.Parse(filesJson))
357+
{
358+
if (doc.RootElement.ValueKind == System.Text.Json.JsonValueKind.Array)
359+
{
360+
files = new List<string>();
361+
foreach (var el in doc.RootElement.EnumerateArray())
362+
{
363+
if (el.ValueKind == System.Text.Json.JsonValueKind.String)
364+
files.Add(el.GetString());
365+
}
366+
}
367+
}
368+
}
369+
370+
if (files != null)
371+
{
372+
foreach (var path in files)
373+
{
374+
try
375+
{
376+
var cleaned = System.Text.RegularExpressions.Regex.Replace(path ?? string.Empty, @"\s*\[(Valid|Invalid)\]", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
377+
if (!string.IsNullOrWhiteSpace(cleaned) && File.Exists(cleaned))
378+
{
379+
checkedListBoxFiles?.Items.Add(cleaned, true);
380+
}
381+
}
382+
catch { /* ignore per-entry errors */ }
383+
}
384+
385+
if (checkedListBoxFiles?.Items != null && checkedListBoxFiles.Items.Count > 0)
386+
{
387+
// Inform user via status bar
388+
statusLabel.Text = @"[INFO] " + checkedListBoxFiles.Items.Count + @" file(s) restored to File List";
389+
}
390+
}
391+
}
392+
}
393+
catch (Exception ex)
394+
{
395+
Message($"Error loading file list from configuration: {ex.Message}", EventType.Error, 3051);
396+
}
397+
325398
// Initialize _previousSignToolPath with the current text box value or a default path
326399
_previousSignToolPath = textBoxSignToolPath.Text;
327400
}
@@ -387,6 +460,41 @@ void SaveGeneralConfig(string encryptedPassword)
387460
// Save encrypted password (or empty if not saving)
388461
iniFile.WriteValue("Program", "CertificatePassword", encryptedPassword ?? "");
389462

463+
// Save last used Trusted Signing options
464+
try
465+
{
466+
iniFile.WriteValue("TrustedSigning", "AccountName", textBoxCodeSigningAccountName.Text ?? string.Empty);
467+
iniFile.WriteValue("TrustedSigning", "CertificateProfile", textBoxCertificateProfileName.Text ?? string.Empty);
468+
}
469+
catch (Exception ex)
470+
{
471+
Message($"Error saving Trusted Signing options: {ex.Message}", EventType.Error, 3052);
472+
}
473+
474+
// Save file list to sign (as JSON array)
475+
try
476+
{
477+
var files = new List<string>();
478+
if (checkedListBoxFiles?.Items != null)
479+
{
480+
foreach (var item in checkedListBoxFiles.Items)
481+
{
482+
var s = item?.ToString() ?? string.Empty;
483+
// Remove any [Valid]/[Invalid] tags before saving
484+
var cleaned = System.Text.RegularExpressions.Regex.Replace(s, @"\s*\[(Valid|Invalid)\]", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
485+
if (!string.IsNullOrWhiteSpace(cleaned))
486+
files.Add(cleaned);
487+
}
488+
}
489+
490+
var json = System.Text.Json.JsonSerializer.Serialize(files);
491+
iniFile.WriteValue("Files", "ToSign", json);
492+
}
493+
catch (Exception ex)
494+
{
495+
Message($"Error saving file list to configuration: {ex.Message}", EventType.Error, 3053);
496+
}
497+
390498
// Save timestamp and certificate type configuration
391499
try { SaveTimestampConfiguration(); } catch (Exception ex) { Message($"Error saving timestamp configuration: {ex.Message}", EventType.Error, 3013); }
392500
try { SaveCertificateTypeConfiguration(); } catch (Exception ex) { Message($"Error saving certificate type configuration: {ex.Message}", EventType.Error, 3030); }
@@ -1147,7 +1255,7 @@ private async Task SignWithPfxCertificateAsync()
11471255
{
11481256
if (string.IsNullOrEmpty(message)) return;
11491257
// Filter out non-essential messages if the output checkbox is not checked.
1150-
if (!checkBoxShowOutput.Checked && new[]
1258+
if (!checkBoxShowOutput.Checked && new[]
11511259
{
11521260
"Number of", "Done Adding Additional Store", "The following certificate was selected:",
11531261
"Signing file", "hash:", "Issued to:", "Issued by:", "Expires:",
@@ -1278,7 +1386,7 @@ private async Task SignWithTrustedSigningAsync()
12781386
{
12791387
if (string.IsNullOrEmpty(message)) return;
12801388
// Filter out non-essential messages if the output checkbox is not checked.
1281-
if (!checkBoxShowOutput.Checked && new[]
1389+
if (!checkBoxShowOutput.Checked && new[]
12821390
{
12831391
"Number of", "Done Adding Additional Store", "The following certificate was selected:",
12841392
"Signing file", "hash:", "Issued to:", "Issued by:", "Expires:",
@@ -1888,6 +1996,7 @@ private void ButtonShowSigningCertificate_Click(object sender, EventArgs e)
18881996
if (radioButtonPFXCertificate.Checked)
18891997
{
18901998
// If the label for certificate information is not null, update it with the certificate info.
1999+
// If no certificate is selected, set the label to indicate that certificate info is not available.
18912000
if (labelCertificateInformation != null)
18922001
labelCertificateInformation.Text = GetCertificateInfo(GetCertificateFromPfx());
18932002

src/SignToolGUI/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("2.0.0.0")]
36-
[assembly: AssemblyFileVersion("2.0.0.0")]
35+
[assembly: AssemblyVersion("2.1.0.0")]
36+
[assembly: AssemblyFileVersion("2.1.0.0")]

0 commit comments

Comments
 (0)