@@ -62,7 +62,7 @@ public DependencyManager(string srcDir, IDependencyOptions options, ILogger logg
62
62
try
63
63
{
64
64
this . dotnet = DotNet . Make ( options , logger , tempWorkingDirectory ) ;
65
- runtimeLazy = new Lazy < Runtime > ( ( ) => new Runtime ( dotnet ) ) ;
65
+ runtimeLazy = new Lazy < Runtime > ( ( ) => new Runtime ( dotnet , logger ) ) ;
66
66
}
67
67
catch
68
68
{
@@ -112,7 +112,7 @@ public DependencyManager(string srcDir, IDependencyOptions options, ILogger logg
112
112
logger . LogInfo ( $ "Unresolved reference { r . Key } in project { r . Value } ") ;
113
113
}
114
114
115
- var webViewExtractionOption = Environment . GetEnvironmentVariable ( "CODEQL_EXTRACTOR_CSHARP_STANDALONE_EXTRACT_WEB_VIEWS" ) ;
115
+ var webViewExtractionOption = Environment . GetEnvironmentVariable ( EnvironmentVariableNames . WebViewGeneration ) ;
116
116
if ( webViewExtractionOption == null ||
117
117
bool . TryParse ( webViewExtractionOption , out var shouldExtractWebViews ) &&
118
118
shouldExtractWebViews )
@@ -159,6 +159,53 @@ private HashSet<string> AddFrameworkDlls(HashSet<string> dllPaths)
159
159
{
160
160
var frameworkLocations = new HashSet < string > ( ) ;
161
161
162
+ var frameworkReferences = Environment . GetEnvironmentVariable ( EnvironmentVariableNames . DotnetFrameworkReferences ) ;
163
+ var frameworkReferencesUseSubfolders = Environment . GetEnvironmentVariable ( EnvironmentVariableNames . DotnetFrameworkReferencesUseSubfolders ) ;
164
+ _ = bool . TryParse ( frameworkReferencesUseSubfolders , out var useSubfolders ) ;
165
+ if ( ! string . IsNullOrWhiteSpace ( frameworkReferences ) )
166
+ {
167
+ RemoveFrameworkNugetPackages ( dllPaths ) ;
168
+ RemoveNugetPackageReference ( FrameworkPackageNames . AspNetCoreFramework , dllPaths ) ;
169
+ RemoveNugetPackageReference ( FrameworkPackageNames . WindowsDesktopFramework , dllPaths ) ;
170
+
171
+ var frameworkPaths = frameworkReferences . Split ( Path . PathSeparator , StringSplitOptions . RemoveEmptyEntries ) ;
172
+
173
+ foreach ( var path in frameworkPaths )
174
+ {
175
+ if ( ! Directory . Exists ( path ) )
176
+ {
177
+ logger . LogError ( $ "Specified framework reference path '{ path } ' does not exist.") ;
178
+ continue ;
179
+ }
180
+
181
+ if ( useSubfolders )
182
+ {
183
+ dllPaths . Add ( path ) ;
184
+ frameworkLocations . Add ( path ) ;
185
+ continue ;
186
+ }
187
+
188
+ try
189
+ {
190
+ var dlls = Directory . GetFiles ( path , "*.dll" , new EnumerationOptions { RecurseSubdirectories = false , MatchCasing = MatchCasing . CaseInsensitive } ) ;
191
+ if ( dlls . Length == 0 )
192
+ {
193
+ logger . LogError ( $ "No DLLs found in specified framework reference path '{ path } '.") ;
194
+ continue ;
195
+ }
196
+
197
+ dllPaths . UnionWith ( dlls ) ;
198
+ frameworkLocations . UnionWith ( dlls ) ;
199
+ }
200
+ catch ( Exception e )
201
+ {
202
+ logger . LogError ( $ "Error while searching for DLLs in '{ path } ': { e . Message } ") ;
203
+ }
204
+ }
205
+
206
+ return frameworkLocations ;
207
+ }
208
+
162
209
AddNetFrameworkDlls ( dllPaths , frameworkLocations ) ;
163
210
AddAspNetCoreFrameworkDlls ( dllPaths , frameworkLocations ) ;
164
211
AddMicrosoftWindowsDesktopDlls ( dllPaths , frameworkLocations ) ;
@@ -204,9 +251,9 @@ private void RestoreNugetPackages(List<FileInfo> allNonBinaryFiles, IEnumerable<
204
251
nugetPackageDllPaths . ExceptWith ( excludedPaths ) ;
205
252
dllPaths . UnionWith ( nugetPackageDllPaths ) ;
206
253
}
207
- catch ( Exception )
254
+ catch ( Exception exc )
208
255
{
209
- logger . LogError ( "Failed to restore Nuget packages with nuget.exe" ) ;
256
+ logger . LogError ( $ "Failed to restore Nuget packages with nuget.exe: { exc . Message } ") ;
210
257
}
211
258
212
259
var restoredProjects = RestoreSolutions ( allSolutions , out var assets1 ) ;
@@ -297,14 +344,23 @@ private static DirectoryInfo[] GetPackageVersionSubDirectories(string packagePat
297
344
. ToArray ( ) ;
298
345
}
299
346
347
+ private void RemoveFrameworkNugetPackages ( ISet < string > dllPaths , int fromIndex = 0 )
348
+ {
349
+ var packagesInPrioOrder = FrameworkPackageNames . NetFrameworks ;
350
+ for ( var i = fromIndex ; i < packagesInPrioOrder . Length ; i ++ )
351
+ {
352
+ RemoveNugetPackageReference ( packagesInPrioOrder [ i ] , dllPaths ) ;
353
+ }
354
+ }
355
+
300
356
private void AddNetFrameworkDlls ( ISet < string > dllPaths , ISet < string > frameworkLocations )
301
357
{
302
358
// Multiple dotnet framework packages could be present.
303
359
// The order of the packages is important, we're adding the first one that is present in the nuget cache.
304
360
var packagesInPrioOrder = FrameworkPackageNames . NetFrameworks ;
305
361
306
362
var frameworkPaths = packagesInPrioOrder
307
- . Select ( ( s , index ) => ( Index : index , Path : GetPackageDirectory ( s ) ) )
363
+ . Select ( ( s , index ) => ( Index : index , Path : GetPackageDirectory ( s , packageDirectory ) ) )
308
364
. Where ( pair => pair . Path is not null )
309
365
. ToArray ( ) ;
310
366
@@ -318,12 +374,7 @@ private void AddNetFrameworkDlls(ISet<string> dllPaths, ISet<string> frameworkLo
318
374
}
319
375
320
376
SelectNewestFrameworkPath ( frameworkPath . Path , ".NET Framework" , dllPaths , frameworkLocations ) ;
321
-
322
- for ( var i = frameworkPath . Index + 1 ; i < packagesInPrioOrder . Length ; i ++ )
323
- {
324
- RemoveNugetPackageReference ( packagesInPrioOrder [ i ] , dllPaths ) ;
325
- }
326
-
377
+ RemoveFrameworkNugetPackages ( dllPaths , frameworkPath . Index + 1 ) ;
327
378
return ;
328
379
}
329
380
@@ -336,6 +387,16 @@ private void AddNetFrameworkDlls(ISet<string> dllPaths, ISet<string> frameworkLo
336
387
else if ( fileContent . IsLegacyProjectStructureUsed )
337
388
{
338
389
runtimeLocation = Runtime . DesktopRuntime ;
390
+
391
+ if ( runtimeLocation is null )
392
+ {
393
+ logger . LogInfo ( "No .NET Desktop Runtime location found. Attempting to restore the .NET Framework reference assemblies manually." ) ;
394
+
395
+ if ( TryRestorePackageManually ( FrameworkPackageNames . LatestNetFrameworkReferenceAssemblies , null ) )
396
+ {
397
+ runtimeLocation = GetPackageDirectory ( FrameworkPackageNames . LatestNetFrameworkReferenceAssemblies , missingPackageDirectory ) ;
398
+ }
399
+ }
339
400
}
340
401
341
402
runtimeLocation ??= Runtime . ExecutingRuntime ;
@@ -375,7 +436,7 @@ private void AddAspNetCoreFrameworkDlls(ISet<string> dllPaths, ISet<string> fram
375
436
}
376
437
377
438
// First try to find ASP.NET Core assemblies in the NuGet packages
378
- if ( GetPackageDirectory ( FrameworkPackageNames . AspNetCoreFramework ) is string aspNetCorePackage )
439
+ if ( GetPackageDirectory ( FrameworkPackageNames . AspNetCoreFramework , packageDirectory ) is string aspNetCorePackage )
379
440
{
380
441
SelectNewestFrameworkPath ( aspNetCorePackage , "ASP.NET Core" , dllPaths , frameworkLocations ) ;
381
442
return ;
@@ -391,15 +452,15 @@ private void AddAspNetCoreFrameworkDlls(ISet<string> dllPaths, ISet<string> fram
391
452
392
453
private void AddMicrosoftWindowsDesktopDlls ( ISet < string > dllPaths , ISet < string > frameworkLocations )
393
454
{
394
- if ( GetPackageDirectory ( FrameworkPackageNames . WindowsDesktopFramework ) is string windowsDesktopApp )
455
+ if ( GetPackageDirectory ( FrameworkPackageNames . WindowsDesktopFramework , packageDirectory ) is string windowsDesktopApp )
395
456
{
396
457
SelectNewestFrameworkPath ( windowsDesktopApp , "Windows Desktop App" , dllPaths , frameworkLocations ) ;
397
458
}
398
459
}
399
460
400
- private string ? GetPackageDirectory ( string packagePrefix )
461
+ private string ? GetPackageDirectory ( string packagePrefix , TemporaryDirectory root )
401
462
{
402
- return new DirectoryInfo ( packageDirectory . DirInfo . FullName )
463
+ return new DirectoryInfo ( root . DirInfo . FullName )
403
464
. EnumerateDirectories ( packagePrefix + "*" , new EnumerationOptions { MatchCasing = MatchCasing . CaseInsensitive , RecurseSubdirectories = false } )
404
465
. FirstOrDefault ( ) ?
405
466
. FullName ;
@@ -435,19 +496,19 @@ private void GenerateSourceFileFromImplicitUsings()
435
496
}
436
497
437
498
// Hardcoded values from https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives
438
- usings . UnionWith ( new [ ] { "System" , "System.Collections.Generic" , "System.IO" , "System.Linq" , "System.Net.Http" , "System.Threading" ,
439
- "System.Threading.Tasks" } ) ;
499
+ usings . UnionWith ( [ "System" , "System.Collections.Generic" , "System.IO" , "System.Linq" , "System.Net.Http" , "System.Threading" ,
500
+ "System.Threading.Tasks" ] ) ;
440
501
441
502
if ( fileContent . UseAspNetCoreDlls )
442
503
{
443
- usings . UnionWith ( new [ ] { "System.Net.Http.Json" , "Microsoft.AspNetCore.Builder" , "Microsoft.AspNetCore.Hosting" ,
504
+ usings . UnionWith ( [ "System.Net.Http.Json" , "Microsoft.AspNetCore.Builder" , "Microsoft.AspNetCore.Hosting" ,
444
505
"Microsoft.AspNetCore.Http" , "Microsoft.AspNetCore.Routing" , "Microsoft.Extensions.Configuration" ,
445
- "Microsoft.Extensions.DependencyInjection" , "Microsoft.Extensions.Hosting" , "Microsoft.Extensions.Logging" } ) ;
506
+ "Microsoft.Extensions.DependencyInjection" , "Microsoft.Extensions.Hosting" , "Microsoft.Extensions.Logging" ] ) ;
446
507
}
447
508
448
509
if ( fileContent . UseWindowsForms )
449
510
{
450
- usings . UnionWith ( new [ ] { "System.Drawing" , "System.Windows.Forms" } ) ;
511
+ usings . UnionWith ( [ "System.Drawing" , "System.Windows.Forms" ] ) ;
451
512
}
452
513
453
514
usings . UnionWith ( fileContent . CustomImplicitUsings ) ;
@@ -869,47 +930,58 @@ private void DownloadMissingPackages(List<FileInfo> allFiles, ISet<string> dllPa
869
930
870
931
Parallel . ForEach ( notYetDownloadedPackages , new ParallelOptions { MaxDegreeOfParallelism = options . Threads } , package =>
871
932
{
872
- logger . LogInfo ( $ "Restoring package { package } ...") ;
873
- using var tempDir = new TemporaryDirectory ( ComputeTempDirectory ( package , "missingpackages_workingdir" ) ) ;
874
- var success = dotnet . New ( tempDir . DirInfo . FullName ) ;
933
+ var success = TryRestorePackageManually ( package , nugetConfig ) ;
875
934
if ( ! success )
876
935
{
877
936
return ;
878
937
}
879
938
880
- success = dotnet . AddPackage ( tempDir . DirInfo . FullName , package ) ;
881
- if ( ! success )
939
+ lock ( sync )
882
940
{
883
- return ;
941
+ successCount ++ ;
884
942
}
943
+ } ) ;
885
944
886
- var res = dotnet . Restore ( new ( tempDir . DirInfo . FullName , missingPackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : false , PathToNugetConfig : nugetConfig ) ) ;
887
- if ( ! res . Success )
888
- {
889
- if ( res . HasNugetPackageSourceError )
890
- {
891
- // Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
892
- res = dotnet . Restore ( new ( tempDir . DirInfo . FullName , missingPackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : false , PathToNugetConfig : null , ForceReevaluation : true ) ) ;
893
- }
945
+ CompilationInfos . Add ( ( "Successfully ran fallback nuget restore" , successCount . ToString ( ) ) ) ;
894
946
895
- // TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
947
+ dllPaths . Add ( missingPackageDirectory . DirInfo . FullName ) ;
948
+ }
896
949
897
- if ( ! res . Success )
898
- {
899
- logger . LogInfo ( $ "Failed to restore nuget package { package } ") ;
900
- return ;
901
- }
902
- }
950
+ private bool TryRestorePackageManually ( string package , string ? nugetConfig )
951
+ {
952
+ logger . LogInfo ( $ "Restoring package { package } ...") ;
953
+ using var tempDir = new TemporaryDirectory ( ComputeTempDirectory ( package , "missingpackages_workingdir" ) ) ;
954
+ var success = dotnet . New ( tempDir . DirInfo . FullName ) ;
955
+ if ( ! success )
956
+ {
957
+ return false ;
958
+ }
903
959
904
- lock ( sync )
960
+ success = dotnet . AddPackage ( tempDir . DirInfo . FullName , package ) ;
961
+ if ( ! success )
962
+ {
963
+ return false ;
964
+ }
965
+
966
+ var res = dotnet . Restore ( new ( tempDir . DirInfo . FullName , missingPackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : false , PathToNugetConfig : nugetConfig ) ) ;
967
+ if ( ! res . Success )
968
+ {
969
+ if ( res . HasNugetPackageSourceError && nugetConfig is not null )
905
970
{
906
- successCount ++ ;
971
+ // Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
972
+ res = dotnet . Restore ( new ( tempDir . DirInfo . FullName , missingPackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : false , PathToNugetConfig : null , ForceReevaluation : true ) ) ;
907
973
}
908
- } ) ;
909
974
910
- CompilationInfos . Add ( ( "Successfully ran fallback nuget restore" , successCount . ToString ( ) ) ) ;
975
+ // TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
911
976
912
- dllPaths . Add ( missingPackageDirectory . DirInfo . FullName ) ;
977
+ if ( ! res . Success )
978
+ {
979
+ logger . LogInfo ( $ "Failed to restore nuget package { package } ") ;
980
+ return false ;
981
+ }
982
+ }
983
+
984
+ return true ;
913
985
}
914
986
915
987
public void Dispose ( TemporaryDirectory ? dir , string name )
0 commit comments