@@ -12,6 +12,8 @@ namespace Sign.Core
1212{
1313 internal sealed class AzureSignToolSigner : IAzureSignToolDataFormatSigner
1414 {
15+ private static readonly string [ ] StaThreadExtensions = [ ".js" , ".vbs" ] ;
16+
1517 private readonly ICertificateProvider _certificateProvider ;
1618 private readonly ISignatureAlgorithmProvider _signatureAlgorithmProvider ;
1719 private readonly ILogger < IDataFormatSigner > _logger ;
@@ -113,25 +115,23 @@ public async Task SignAsync(IEnumerable<FileInfo> files, SignOptions options)
113115 options . FileHashAlgorithm ,
114116 timestampConfiguration ) )
115117 {
118+ FileInfo [ ] staThreadFiles = [ .. files . Where ( file => StaThreadExtensions . Contains ( file . Extension ) ) ] ;
119+ foreach ( FileInfo file in staThreadFiles )
120+ {
121+ await RunOnStaThread ( ( ) => SignAsync ( signer , file , options ) ) ;
122+ }
123+
116124 // loop through all of the files here, looking for appx/eappx
117125 // mark each as being signed and strip appx
118126 await Parallel . ForEachAsync ( files , async ( file , state ) =>
119127 {
120- if ( ! await SignAsync ( signer , file , options ) )
121- {
122- string message = string . Format ( CultureInfo . CurrentCulture , Resources . SigningFailed , file . FullName ) ;
123-
124- throw new SigningException ( message ) ;
125- }
128+ await SignAsync ( signer , file , options ) ;
126129 } ) ;
127130 }
128131 }
129132
130133 // Inspired from https://github.com/squaredup/bettersigntool/blob/master/bettersigntool/bettersigntool/SignCommand.cs
131- private async Task < bool > SignAsync (
132- AuthenticodeKeyVaultSigner signer ,
133- FileInfo file ,
134- SignOptions options )
134+ private async Task SignAsync ( AuthenticodeKeyVaultSigner signer , FileInfo file , SignOptions options )
135135 {
136136 TimeSpan retry = TimeSpan . FromSeconds ( 5 ) ;
137137 const int maxAttempts = 3 ;
@@ -148,7 +148,7 @@ private async Task<bool> SignAsync(
148148
149149 if ( RunSignTool ( signer , file , options ) )
150150 {
151- return true ;
151+ return ;
152152 }
153153
154154 ++ attempt ;
@@ -157,7 +157,9 @@ private async Task<bool> SignAsync(
157157
158158 _logger . LogError ( Resources . SigningFailedAfterAllAttempts ) ;
159159
160- return false ;
160+ string message = string . Format ( CultureInfo . CurrentCulture , Resources . SigningFailed , file . FullName ) ;
161+
162+ throw new SigningException ( message ) ;
161163 }
162164
163165 private bool RunSignTool ( AuthenticodeKeyVaultSigner signer , FileInfo file , SignOptions options )
@@ -198,5 +200,31 @@ private bool RunSignTool(AuthenticodeKeyVaultSigner signer, FileInfo file, SignO
198200
199201 return false ;
200202 }
203+
204+ private static Task < bool > RunOnStaThread ( Func < Task > func )
205+ {
206+ if ( ! OperatingSystem . IsWindows ( ) )
207+ {
208+ throw new NotSupportedException ( ) ;
209+ }
210+
211+ TaskCompletionSource < bool > taskCompletionSource = new ( ) ;
212+ var thread = new Thread ( async ( ) =>
213+ {
214+ try
215+ {
216+ await func ( ) ;
217+ taskCompletionSource . SetResult ( true ) ;
218+ }
219+ catch ( Exception exception )
220+ {
221+ taskCompletionSource . SetException ( exception ) ;
222+ }
223+ } ) ;
224+
225+ thread . SetApartmentState ( ApartmentState . STA ) ;
226+ thread . Start ( ) ;
227+ return taskCompletionSource . Task ;
228+ }
201229 }
202230}
0 commit comments