Skip to content

Conversation

dlemstra
Copy link
Collaborator

Fixes #880

@dlemstra dlemstra requested a review from a team as a code owner May 23, 2025 16:01
@dlemstra dlemstra force-pushed the js-vbs-in-sta-thread branch from a71f3e7 to 4504884 Compare May 24, 2025 07:45

// loop through all of the files here, looking for appx/eappx
// mark each as being signed and strip appx
await Parallel.ForEachAsync(files, async (file, state) =>
Copy link
Collaborator

@dtivel dtivel Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the fix by signing a single .js file. The STA signing above succeeded, but this failed because it tries to sign all files on an MTA thread, which was the original problem.

This statement should sign all files that don't have a file extension in StaThreadExtensions.

We should have test coverage.

{
internal sealed class AzureSignToolSigner : IAzureSignToolDataFormatSigner
{
private static readonly string[] StaThreadExtensions = [".js", ".vbs"];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparisons should be case-insensitive.

Suggested change
private static readonly string[] StaThreadExtensions = [".js", ".vbs"];
private static readonly HashSet<string> StaThreadExtensions = new(StringComparer.OrdinalIgnoreCase)
{
".js",
".vbs"
};

return false;
}

private static Task<bool> RunOnStaThread(Func<Task> func)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static Task<bool> RunOnStaThread(Func<Task> func)
private static Task<bool> RunOnStaThreadAsync(Func<Task> func)

FileInfo[] staThreadFiles = [.. files.Where(file => StaThreadExtensions.Contains(file.Extension))];
foreach (FileInfo file in staThreadFiles)
{
await RunOnStaThread(() => SignAsync(signer, file, options));
Copy link
Collaborator

@dtivel dtivel Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works because the actual signing operation happens to execute synchronously before any await calls. SignAsync(...) does contain an await Thread.Delay(...), but it only executes on retry. With the current implementation, only the first try has any chance of success while subsequent retries are guaranteed to fail because execution will resume on the thread pool (MTA).

The proper fix involves setting a synchronization context on the STA thread so that all continuations resume on the STA thread.

https://devblogs.microsoft.com/dotnet/await-synchronizationcontext-and-console-apps/
https://devblogs.microsoft.com/dotnet/await-synchronizationcontext-and-console-apps-part-2/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

VBS files inside nupkg fail to sign
2 participants