-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathResolveAssemblyReference.cs
3271 lines (2919 loc) · 160 KB
/
ResolveAssemblyReference.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
#if !NET
using System.Globalization;
#endif
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using Microsoft.Build.Eventing;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;
using Microsoft.Build.Shared.FileSystem;
using Microsoft.Build.Tasks.AssemblyDependency;
using Microsoft.Build.Utilities;
using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName;
using SystemProcessorArchitecture = System.Reflection.ProcessorArchitecture;
#nullable disable
namespace Microsoft.Build.Tasks
{
/// <summary>
/// Given a list of assemblyFiles, determine the closure of all assemblyFiles that
/// depend on those assemblyFiles including second and nth-order dependencies too.
/// </summary>
public class ResolveAssemblyReference : TaskExtension, IIncrementalTask
{
/// <summary>
/// key assembly used to trigger inclusion of facade references.
/// </summary>
private const string SystemRuntimeAssemblyName = "System.Runtime";
/// <summary>
/// additional key assembly used to trigger inclusion of facade references.
/// </summary>
private const string NETStandardAssemblyName = "netstandard";
/// <summary>
/// The well-known CLR 4.0 metadata version used in all managed assemblies.
/// </summary>
private const string DotNetAssemblyRuntimeVersion = "v4.0.30319";
/// <summary>
/// Delegate to a method that takes a targetFrameworkDirectory and returns an array of redist or subset list paths
/// </summary>
/// <param name="targetFrameworkDirectory">TargetFramework directory to search for redist or subset list</param>
/// <returns>String array of redist or subset lists</returns>
private delegate string[] GetListPath(string targetFrameworkDirectory);
/// <summary>
/// Cache of system state information, used to optimize performance.
/// </summary>
internal SystemState _cache = null;
/// <summary>
/// Construct
/// </summary>
public ResolveAssemblyReference()
{
Strings.Initialize(Log);
}
private static class Strings
{
public const string FourSpaces = " ";
public const string EightSpaces = " ";
public const string TenSpaces = " ";
public const string TwelveSpaces = " ";
public static string ConsideredAndRejectedBecauseFusionNamesDidntMatch;
public static string ConsideredAndRejectedBecauseNoFile;
public static string ConsideredAndRejectedBecauseNotAFileNameOnDisk;
public static string ConsideredAndRejectedBecauseNotInGac;
public static string ConsideredAndRejectedBecauseTargetDidntHaveFusionName;
public static string Dependency;
public static string FormattedAssemblyInfo;
public static string FoundRelatedFile;
public static string FoundSatelliteFile;
public static string FoundScatterFile;
public static string ImageRuntimeVersion;
public static string IsAWinMdFile;
public static string LogAttributeFormat;
public static string LogTaskPropertyFormat;
public static string NoBecauseParentReferencesFoundInGac;
public static string NoBecauseBadImage;
public static string NotCopyLocalBecauseConflictVictim;
public static string NotCopyLocalBecauseEmbedded;
public static string NotCopyLocalBecauseFrameworksFiles;
public static string NotCopyLocalBecauseIncomingItemAttributeOverrode;
public static string NotCopyLocalBecausePrerequisite;
public static string NotCopyLocalBecauseReferenceFoundInGAC;
public static string PrimaryReference;
public static string RemappedReference;
public static string RequiredBy;
public static string Resolved;
public static string ResolvedFrom;
public static string SearchedAssemblyFoldersEx;
public static string SearchPath;
public static string SearchPathAddedByParentAssembly;
public static string TargetedProcessorArchitectureDoesNotMatch;
public static string UnificationByAppConfig;
public static string UnificationByAutoUnify;
public static string UnificationByFrameworkRetarget;
public static string UnifiedDependency;
public static string UnifiedPrimaryReference;
private static bool initialized = false;
internal static void Initialize(TaskLoggingHelper log)
{
if (initialized)
{
return;
}
initialized = true;
string GetResource(string name) => log.GetResourceMessage(name);
string GetResourceFourSpaces(string name) => FourSpaces + log.GetResourceMessage(name);
string GetResourceEightSpaces(string name) => EightSpaces + log.GetResourceMessage(name);
ConsideredAndRejectedBecauseFusionNamesDidntMatch = GetResourceEightSpaces("ResolveAssemblyReference.ConsideredAndRejectedBecauseFusionNamesDidntMatch");
ConsideredAndRejectedBecauseNoFile = GetResourceEightSpaces("ResolveAssemblyReference.ConsideredAndRejectedBecauseNoFile");
ConsideredAndRejectedBecauseNotAFileNameOnDisk = GetResourceEightSpaces("ResolveAssemblyReference.ConsideredAndRejectedBecauseNotAFileNameOnDisk");
ConsideredAndRejectedBecauseNotInGac = GetResourceEightSpaces("ResolveAssemblyReference.ConsideredAndRejectedBecauseNotInGac");
ConsideredAndRejectedBecauseTargetDidntHaveFusionName = GetResourceEightSpaces("ResolveAssemblyReference.ConsideredAndRejectedBecauseTargetDidntHaveFusionName");
Dependency = GetResource("ResolveAssemblyReference.Dependency");
FormattedAssemblyInfo = GetResourceFourSpaces("ResolveAssemblyReference.FormattedAssemblyInfo");
FoundRelatedFile = GetResourceFourSpaces("ResolveAssemblyReference.FoundRelatedFile");
FoundSatelliteFile = GetResourceFourSpaces("ResolveAssemblyReference.FoundSatelliteFile");
FoundScatterFile = GetResourceFourSpaces("ResolveAssemblyReference.FoundScatterFile");
ImageRuntimeVersion = GetResourceFourSpaces("ResolveAssemblyReference.ImageRuntimeVersion");
IsAWinMdFile = GetResourceFourSpaces("ResolveAssemblyReference.IsAWinMdFile");
LogAttributeFormat = GetResourceEightSpaces("ResolveAssemblyReference.LogAttributeFormat");
LogTaskPropertyFormat = GetResource("ResolveAssemblyReference.LogTaskPropertyFormat");
NoBecauseBadImage = GetResourceFourSpaces("ResolveAssemblyReference.NoBecauseBadImage");
NoBecauseParentReferencesFoundInGac = GetResourceFourSpaces("ResolveAssemblyReference.NoBecauseParentReferencesFoundInGac");
NotCopyLocalBecauseConflictVictim = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecauseConflictVictim");
NotCopyLocalBecauseEmbedded = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecauseEmbedded");
NotCopyLocalBecauseFrameworksFiles = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecauseFrameworksFiles");
NotCopyLocalBecauseIncomingItemAttributeOverrode = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecauseIncomingItemAttributeOverrode");
NotCopyLocalBecausePrerequisite = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecausePrerequisite");
NotCopyLocalBecauseReferenceFoundInGAC = GetResourceFourSpaces("ResolveAssemblyReference.NotCopyLocalBecauseReferenceFoundInGAC");
PrimaryReference = GetResource("ResolveAssemblyReference.PrimaryReference");
RemappedReference = GetResourceFourSpaces("ResolveAssemblyReference.RemappedReference");
RequiredBy = GetResourceFourSpaces("ResolveAssemblyReference.RequiredBy");
Resolved = GetResourceFourSpaces("ResolveAssemblyReference.Resolved");
ResolvedFrom = GetResourceFourSpaces("ResolveAssemblyReference.ResolvedFrom");
SearchedAssemblyFoldersEx = GetResourceEightSpaces("ResolveAssemblyReference.SearchedAssemblyFoldersEx");
SearchPath = GetResourceEightSpaces("ResolveAssemblyReference.SearchPath");
SearchPathAddedByParentAssembly = GetResourceEightSpaces("ResolveAssemblyReference.SearchPathAddedByParentAssembly");
TargetedProcessorArchitectureDoesNotMatch = GetResourceEightSpaces("ResolveAssemblyReference.TargetedProcessorArchitectureDoesNotMatch");
UnificationByAppConfig = GetResourceFourSpaces("ResolveAssemblyReference.UnificationByAppConfig");
UnificationByAutoUnify = GetResourceFourSpaces("ResolveAssemblyReference.UnificationByAutoUnify");
UnificationByFrameworkRetarget = GetResourceFourSpaces("ResolveAssemblyReference.UnificationByFrameworkRetarget");
UnifiedDependency = GetResource("ResolveAssemblyReference.UnifiedDependency");
UnifiedPrimaryReference = GetResource("ResolveAssemblyReference.UnifiedPrimaryReference");
}
}
#region Properties
private ITaskItem[] _assemblyFiles = Array.Empty<TaskItem>();
private ITaskItem[] _assemblyNames = Array.Empty<TaskItem>();
private ITaskItem[] _installedAssemblyTables = Array.Empty<TaskItem>();
private ITaskItem[] _installedAssemblySubsetTables = Array.Empty<TaskItem>();
private ITaskItem[] _fullFrameworkAssemblyTables = Array.Empty<TaskItem>();
private ITaskItem[] _resolvedSDKReferences = Array.Empty<TaskItem>();
private bool _ignoreDefaultInstalledAssemblyTables = false;
private bool _ignoreDefaultInstalledAssemblySubsetTables = false;
private bool _enableCustomCulture = false;
private string[] _candidateAssemblyFiles = [];
private string[] _targetFrameworkDirectories = [];
private string[] _nonCultureResourceDirectories = [];
private string[] _searchPaths = [];
private string[] _allowedAssemblyExtensions = [".winmd", ".dll", ".exe"];
private string[] _relatedFileExtensions = [".pdb", ".xml", ".pri"];
private string _appConfigFile = null;
private bool _supportsBindingRedirectGeneration;
private bool _autoUnify = false;
private bool _ignoreVersionForFrameworkReferences = false;
private bool _ignoreTargetFrameworkAttributeVersionMismatch = false;
private ITaskItem[] _resolvedFiles = Array.Empty<TaskItem>();
private ITaskItem[] _resolvedDependencyFiles = Array.Empty<TaskItem>();
private ITaskItem[] _relatedFiles = Array.Empty<TaskItem>();
private ITaskItem[] _satelliteFiles = Array.Empty<TaskItem>();
private ITaskItem[] _serializationAssemblyFiles = Array.Empty<TaskItem>();
private ITaskItem[] _scatterFiles = Array.Empty<TaskItem>();
private ITaskItem[] _copyLocalFiles = Array.Empty<TaskItem>();
private ITaskItem[] _suggestedRedirects = Array.Empty<TaskItem>();
private List<ITaskItem> _unresolvedConflicts = new List<ITaskItem>();
private string[] _targetFrameworkSubsets = [];
private string[] _fullTargetFrameworkSubsetNames = [];
private string _targetedFrameworkMoniker = String.Empty;
private bool _findDependencies = true;
private bool _findSatellites = true;
private bool _findSerializationAssemblies = true;
private bool _findRelatedFiles = true;
private bool _silent = false;
private string _projectTargetFrameworkAsString = String.Empty;
private string _targetedRuntimeVersionRawValue = String.Empty;
private Version _projectTargetFramework;
private string _stateFile = null;
private string _targetProcessorArchitecture = null;
private string _profileName = String.Empty;
private string[] _fullFrameworkFolders = [];
private string[] _latestTargetFrameworkDirectories = [];
private bool _copyLocalDependenciesWhenParentReferenceInGac = true;
private Dictionary<string, MessageImportance> _showAssemblyFoldersExLocations = new Dictionary<string, MessageImportance>(StringComparer.OrdinalIgnoreCase);
private bool _logVerboseSearchResults = false;
private WarnOrErrorOnTargetArchitectureMismatchBehavior _warnOrErrorOnTargetArchitectureMismatch = WarnOrErrorOnTargetArchitectureMismatchBehavior.Warning;
private bool _unresolveFrameworkAssembliesFromHigherFrameworks = false;
/// <summary>
/// If set to true, it forces to unresolve framework assemblies with versions higher or equal the version of the target framework, regardless of the target framework
/// </summary>
public bool UnresolveFrameworkAssembliesFromHigherFrameworks
{
get
{
return _unresolveFrameworkAssembliesFromHigherFrameworks;
}
set
{
_unresolveFrameworkAssembliesFromHigherFrameworks = value;
}
}
/// <summary>
/// If there is a mismatch between the targetprocessor architecture and the architecture of a primary reference.
///
/// When this is error, an error will be logged.
///
/// When this is warn, if there is a mismatch between the targetprocessor architecture and the architecture of a primary reference a warning will be logged.
///
/// When this is none, no error or warning will be logged.
/// </summary>
public string WarnOrErrorOnTargetArchitectureMismatch
{
get
{
return _warnOrErrorOnTargetArchitectureMismatch.ToString();
}
set
{
if (!Enum.TryParse<WarnOrErrorOnTargetArchitectureMismatchBehavior>(value, /*ignoreCase*/true, out _warnOrErrorOnTargetArchitectureMismatch))
{
_warnOrErrorOnTargetArchitectureMismatch = WarnOrErrorOnTargetArchitectureMismatchBehavior.Warning;
}
}
}
/// <summary>
/// A list of fully qualified paths-to-assemblyFiles to find dependencies for.
///
/// Optional attributes are:
/// bool Private [default=true] -- means 'CopyLocal'
/// string FusionName -- the simple or strong fusion name for this item. If this
/// attribute is present it can save time since the assembly file won't need
/// to be opened to get the fusion name.
/// bool ExternallyResolved [default=false] -- indicates that the reference and its
/// dependencies are resolved by an external system (commonly from nuget assets) and
/// so several steps can be skipped as an optimization: finding dependencies,
/// satellite assemblies, etc.
/// </summary>
public ITaskItem[] AssemblyFiles
{
get { return _assemblyFiles; }
set { _assemblyFiles = value; }
}
/// <summary>
/// The list of directories which contain the redist lists for the most current
/// framework which can be targeted on the machine. If this is not set
/// Then we will looks for the highest framework installed on the machine
/// for a given target framework identifier and use that.
/// </summary>
public string[] LatestTargetFrameworkDirectories
{
get
{
return _latestTargetFrameworkDirectories;
}
set
{
_latestTargetFrameworkDirectories = value;
}
}
/// <summary>
/// Should the framework attribute be ignored when checking to see if an assembly is compatible with the targeted framework.
/// </summary>
public bool IgnoreTargetFrameworkAttributeVersionMismatch
{
get
{
return _ignoreTargetFrameworkAttributeVersionMismatch;
}
set
{
_ignoreTargetFrameworkAttributeVersionMismatch = value;
}
}
/// <summary>
/// Force dependencies to be walked even when a reference is marked with ExternallyResolved=true
/// metadata.
/// </summary>
/// <remarks>
/// This is used to ensure that we suggest appropriate binding redirects for assembly version
/// conflicts within an externally resolved graph.
/// </remarks>
public bool FindDependenciesOfExternallyResolvedReferences { get; set; }
/// <summary>
/// If true, outputs any unresolved assembly conflicts (MSB3277) in UnresolvedAssemblyConflicts.
/// </summary>
public bool OutputUnresolvedAssemblyConflicts { get; set; }
/// <summary>
/// List of target framework subset names which will be searched for in the target framework directories
/// </summary>
public string[] TargetFrameworkSubsets
{
get
{
return _targetFrameworkSubsets;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "TargetFrameworkSubsets");
_targetFrameworkSubsets = value;
}
}
/// <summary>
/// These can either be simple fusion names like:
///
/// System
///
/// or strong names like
///
/// System, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
///
/// These names will be resolved into full paths and all dependencies will be found.
///
/// Optional attributes are:
/// bool Private [default=true] -- means 'CopyLocal'
/// string HintPath [default=''] -- location of file name to consider as a reference,
/// used when {HintPathFromItem} is one of the paths in SearchPaths.
/// bool SpecificVersion [default=absent] --
/// when true, the exact fusionname in the Include must be matched.
/// when false, any assembly with the same simple name will be a match.
/// when absent, then look at the value in Include.
/// If its a simple name then behave as if specific version=false.
/// If its a strong name then behave as if specific version=true.
/// string ExecutableExtension [default=absent] --
/// when present, the resolved assembly must have this extension.
/// when absent, .dll is considered and then .exe for each directory looked at.
/// string SubType -- only items with empty SubTypes will be considered. Items
/// with non-empty subtypes will be ignored.
/// string AssemblyFolderKey [default=absent] -- supported for legacy AssemblyFolder
/// resolution. This key can have a value like 'hklm\vendor folder'. When set, only
/// this particular assembly folder key will be used.
/// This is to support the scenario in VSWhidey#357946 in which there are multiple
/// side-by-side libraries installed and the user wants to pick an exact version.
/// bool EmbedInteropTyeps [default=absent] --
/// when true, we should treat this assembly as if it has no dependencies and should
/// be completely embedded into the target assembly.
/// </summary>
public ITaskItem[] Assemblies
{
get { return _assemblyNames; }
set { _assemblyNames = value; }
}
/// <summary>
/// A list of assembly files that can be part of the search and resolution process.
/// These must be absolute filenames, or project-relative filenames.
///
/// Assembly files in this list will be considered when SearchPaths contains
/// {CandidateAssemblyFiles} as one of the paths to consider.
/// </summary>
public string[] CandidateAssemblyFiles
{
get { return _candidateAssemblyFiles; }
set { _candidateAssemblyFiles = value; }
}
/// <summary>
/// A list of resolved SDK references which contain the sdk name, sdk location and the targeted configuration.
/// These locations will only be searched if the reference has the SDKName metadata attached to it.
/// </summary>
public ITaskItem[] ResolvedSDKReferences
{
get { return _resolvedSDKReferences; }
set { _resolvedSDKReferences = value; }
}
/// <summary>
/// Path to the target frameworks directory. Required to figure out CopyLocal status
/// for resulting items.
/// If not present, then no resulting items will be deemed CopyLocal='true' unless they explicity
/// have a Private='true' attribute on their source item.
/// </summary>
public string[] TargetFrameworkDirectories
{
get { return _targetFrameworkDirectories; }
set { _targetFrameworkDirectories = value; }
}
/// <summary>
/// Contains list of directories that point to custom culture resources that has to be ignored by MSBuild.
/// </summary>
public string[] NonCultureResourceDirectories
{
get { return _nonCultureResourceDirectories; }
set { _nonCultureResourceDirectories = value; }
}
/// <summary>
/// Contains the information if custom culture is enabled.
/// </summary>
public bool EnableCustomCulture
{
get { return _enableCustomCulture; }
set { _enableCustomCulture = value; }
}
/// <summary>
/// A list of XML files that contain assemblies that are expected to be installed on the target machine.
///
/// Format of the file is like:
///
/// <FileList Redist="Microsoft-Windows-CLRCoreComp" >
/// <File AssemblyName="System" Version="2.0.0.0" PublicKeyToken="b77a5c561934e089" Culture="neutral" ProcessorArchitecture="MSIL" FileVersion="2.0.40824.0" InGAC="true" />
/// etc.
/// </FileList>
///
/// When present, assemblies from this list will be candidates to automatically "unify" from prior versions up to
/// the version listed in the XML. Also, assemblies with InGAC='true' will be considered prerequisites and will be CopyLocal='false'
/// unless explicitly overridden.
/// Items in this list may optionally specify the "FrameworkDirectory" metadata to associate an InstalledAssemblyTable
/// with a particular framework directory. However, this setting will be ignored unless the Redist name begins with
/// "Microsoft-Windows-CLRCoreComp".
/// If there is only a single TargetFrameworkDirectories element, then any items in this list missing the
/// "FrameworkDirectory" metadata will be treated as though this metadata is set to the lone (unique) value passed
/// to TargetFrameworkDirectories.
/// </summary>
public ITaskItem[] InstalledAssemblyTables
{
get { return _installedAssemblyTables; }
set { _installedAssemblyTables = value; }
}
/// <summary>
/// A list of XML files that contain assemblies that are expected to be in the target subset
///
/// Format of the file is like:
///
/// <FileList Redist="ClientSubset" >
/// <File AssemblyName="System" Version="2.0.0.0" PublicKeyToken="b77a5c561934e089" Culture="neutral" ProcessorArchitecture="MSIL" FileVersion="2.0.40824.0" InGAC="true" />
/// etc.
/// </FileList>
///
/// Items in this list may optionally specify the "FrameworkDirectory" metadata to associate an InstalledAssemblySubsetTable
/// with a particular framework directory.
/// If there is only a single TargetFrameworkDirectories element, then any items in this list missing the
/// "FrameworkDirectory" metadata will be treated as though this metadata is set to the lone (unique) value passed
/// to TargetFrameworkDirectories.
/// </summary>
public ITaskItem[] InstalledAssemblySubsetTables
{
get
{
return _installedAssemblySubsetTables;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "InstalledAssemblySubsetTables");
_installedAssemblySubsetTables = value;
}
}
/// <summary>
/// A list of XML files that contain the full framework for the profile.
///
/// Normally nothing is passed in here, this is for the cases where the location of the xml file for the full framework
/// is not under a RedistList folder.
///
/// Format of the file is like:
///
/// <FileList Redist="MatchingRedistListName" >
/// <File AssemblyName="System" Version="2.0.0.0" PublicKeyToken="b77a5c561934e089" Culture="neutral" ProcessorArchitecture="MSIL" FileVersion="2.0.40824.0" InGAC="true" />
/// etc.
/// </FileList>
///
/// Items in this list must specify the "FrameworkDirectory" metadata to associate an redist list
/// with a particular framework directory. If the association is not made an error will be logged. The reason is,
/// The logic in rar assumes if a FrameworkDirectory is not set it will use the target framework directory.
/// </summary>
public ITaskItem[] FullFrameworkAssemblyTables
{
get
{
return _fullFrameworkAssemblyTables;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "FullFrameworkAssemblyTables");
_fullFrameworkAssemblyTables = value;
}
}
/// <summary>
/// [default=false]
/// Boolean property to control whether or not the task should look for and use additional installed
/// assembly tables (a.k.a Redist Lists) found in the RedistList directory underneath the provided
/// TargetFrameworkDirectories.
/// </summary>
public bool IgnoreDefaultInstalledAssemblyTables
{
get { return _ignoreDefaultInstalledAssemblyTables; }
set { _ignoreDefaultInstalledAssemblyTables = value; }
}
/// <summary>
/// [default=false]
/// Boolean property to control whether or not the task should look for and use additional installed
/// assembly subset tables (a.k.a Subset Lists) found in the SubsetList directory underneath the provided
/// TargetFrameworkDirectories.
/// </summary>
public bool IgnoreDefaultInstalledAssemblySubsetTables
{
get { return _ignoreDefaultInstalledAssemblySubsetTables; }
set { _ignoreDefaultInstalledAssemblySubsetTables = value; }
}
/// <summary>
/// If the primary reference is a framework assembly ignore its version information and actually resolve the framework assembly from the currently targeted framework.
/// </summary>
public bool IgnoreVersionForFrameworkReferences
{
get { return _ignoreVersionForFrameworkReferences; }
set { _ignoreVersionForFrameworkReferences = value; }
}
/// <summary>
/// The preferred target processor architecture. Used for resolving {GAC} references.
/// Should be like x86, IA64 or AMD64.
///
/// This is the order of preference:
/// (1) Assemblies in the GAC that match the supplied ProcessorArchitecture.
/// (2) Assemblies in the GAC that have ProcessorArchitecture=MSIL
/// (3) Assemblies in the GAC that have no ProcessorArchitecture.
///
/// If absent, then only consider assemblies in the GAC that have ProcessorArchitecture==MSIL or
/// no ProcessorArchitecture (these are pre-Whidbey assemblies).
/// </summary>
public string TargetProcessorArchitecture
{
get { return _targetProcessorArchitecture; }
set { _targetProcessorArchitecture = value; }
}
/// <summary>
/// What is the runtime we are targeting, is it 2.0.57027 or anotherone, It can have a v or not prefixed onto it.
/// </summary>
public string TargetedRuntimeVersion
{
get { return _targetedRuntimeVersionRawValue; }
set { _targetedRuntimeVersionRawValue = value; }
}
/// <summary>
/// If not null, serializes information about <see cref="AssemblyFiles" /> inputs to the named file.
/// This overrides the usual outputs, so do not use this unless you are building an SDK with many references.
/// </summary>
public string AssemblyInformationCacheOutputPath { get; set; }
/// <summary>
/// If not null, uses this set of caches as inputs if RAR cannot find the usual cache in the obj folder. Typically
/// used for demos and first-run scenarios.
/// </summary>
public ITaskItem[] AssemblyInformationCachePaths { get; set; }
/// <summary>
/// List of locations to search for assemblyFiles when resolving dependencies.
/// The following types of things can be passed in here:
/// (1) A plain old directory path.
/// (2) {HintPathFromItem} -- Look at the HintPath attribute from the base item.
/// This attribute must be a file name *not* a directory name.
/// (3) {CandidateAssemblyFiles} -- Look at the files passed in through the CandidateAssemblyFiles
/// parameter.
/// (4) {Registry:_AssemblyFoldersBase_,_RuntimeVersion_,_AssemblyFoldersSuffix_}
/// Where:
///
/// _AssemblyFoldersBase_ = Software\Microsoft\[.NetFramework | .NetCompactFramework]
/// _RuntimeVersion_ = the runtime version property from the project file
/// _AssemblyFoldersSuffix_ = [ PocketPC | SmartPhone | WindowsCE]\AssemblyFoldersEx
///
/// Then look in the registry for keys with the following schema:
///
/// [HKLM | HKCU]\SOFTWARE\MICROSOFT\.NetFramework\
/// v1.0.3705
/// AssemblyFoldersEx
/// ControlVendor.GridControl.1.0:
/// @Default = c:\program files\ControlVendor\grid control\1.0\bin
/// @Description = Grid Control for .NET version 1.0
/// 9466
/// @Default = c:\program files\ControlVendor\grid control\1.0sp1\bin
/// @Description = SP1 for Grid Control for .NET version 1.0
///
/// The based registry key is composed as:
///
/// [HKLM | HKCU]\_AssemblyFoldersBase_\_RuntimeVersion_\_AssemblyFoldersSuffix_
///
/// (5) {AssemblyFolders} -- Use the VisualStudion 2003 .NET finding-assemblies-from-registry scheme.
/// (6) {GAC} -- Look in the GAC.
/// (7) {RawFileName} -- Consider the Include value to be an exact path and file name.
///
///
/// </summary>
/// <value></value>
[Required]
public string[] SearchPaths
{
get { return _searchPaths; }
set { _searchPaths = value; }
}
/// <summary>
/// [default=.exe;.dll]
/// These are the assembly extensions that will be considered during references resolution.
/// </summary>
public string[] AllowedAssemblyExtensions
{
get { return _allowedAssemblyExtensions; }
set { _allowedAssemblyExtensions = value; }
}
/// <summary>
/// [default=.pdb;.xml]
/// These are the extensions that will be considered when looking for related files.
/// </summary>
public string[] AllowedRelatedFileExtensions
{
get { return _relatedFileExtensions; }
set { _relatedFileExtensions = value; }
}
/// <summary>
/// If this file name is passed in, then we parse it as an app.config file and extract bindingRedirect mappings. These mappings are used in the dependency
/// calculation process to remap versions of assemblies.
///
/// If this parameter is passed in, then AutoUnify must be false, otherwise error.
/// </summary>
/// <value></value>
public string AppConfigFile
{
get { return _appConfigFile; }
set { _appConfigFile = value; }
}
/// <summary>
/// This is true if the project type supports "AutoGenerateBindingRedirects" (currently only for EXE projects).
/// </summary>
/// <value></value>
public bool SupportsBindingRedirectGeneration
{
get { return _supportsBindingRedirectGeneration; }
set { _supportsBindingRedirectGeneration = value; }
}
/// <summary>
/// [default=false]
/// This parameter is used for building assemblies, such as DLLs, which cannot have a normal
/// App.Config file.
///
/// When true, the resulting dependency graph is automatically treated as if there were an
/// App.Config file passed in to the AppConfigFile parameter. This virtual
/// App.Config file has a bindingRedirect entry for each conflicting set of assemblies such
/// that the highest version assembly is chosen. A consequence of this is that there will never
/// be a warning about conflicting assemblies because every conflict will have been resolved.
///
/// When true, each distinct remapping will result in a high priority comment indicating the
/// old and new versions and the fact that this was done automatically because AutoUnify was true.
///
/// When true, the AppConfigFile parameter should be empty. Otherwise, it's an
/// error.
///
/// When false, no assembly version remapping will occur automatically. When two versions of an
/// assembly are present, there will be a warning.
///
/// When false, each distinct conflict between different versions of the same assembly will
/// result in a high priority comment. After all of these comments are displayed, there will be
/// a single warning with a unique error code and text that reads "Found conflicts between
/// different versions of reference and dependent assemblies".
/// </summary>
/// <value></value>
public bool AutoUnify
{
get { return _autoUnify; }
set { _autoUnify = value; }
}
/// <summary>
/// When determining if a dependency should be copied locally one of the checks done is to see if the
/// parent reference in the project file has the Private metadata set or not. If that metadata is set then
/// We will use that for the dependency as well.
///
/// However, if the metadata is not set then the dependency will go through the same checks as the parent reference.
/// One of these checks is to see if the reference is in the GAC. If a reference is in the GAC then we will not copy it locally
/// as it is assumed it will be in the gac on the target machine as well. However this only applies to that specific reference and not its dependencies.
///
/// This means a reference in the project file may be copy local false due to it being in the GAC but the dependencies may still be copied locally because they are not in the GAC.
/// This is the default behavior for RAR and causes the default value for this property to be true.
///
/// When this property is false we will still check project file references to see if they are in the GAC and set their copy local state as appropriate.
/// However for dependencies we will not only check to see if they are in the GAC but we will also check to see if the parent reference from the project file is in the GAC.
/// If the parent reference from the project file is in the GAC then we will not copy the dependency locally.
///
/// NOTE: If there are multiple parent reference and ANY of them does not come from the GAC then we will set copy local to true.
/// </summary>
public bool CopyLocalDependenciesWhenParentReferenceInGac
{
get { return _copyLocalDependenciesWhenParentReferenceInGac; }
set { _copyLocalDependenciesWhenParentReferenceInGac = value; }
}
/// <summary>
/// [default=false]
/// Enables legacy mode for CopyLocal determination. If true, referenced assemblies will not be copied locally if they
/// are found in the GAC. If false, assemblies will be copied locally unless they were found only in the GAC.
/// </summary>
public bool DoNotCopyLocalIfInGac
{
get;
set;
}
/// <summary>
/// An optional file name that indicates where to save intermediate build state
/// for this task. If not specified, then no inter-build caching will occur.
/// </summary>
/// <value></value>
public string StateFile
{
get { return _stateFile; }
set { _stateFile = value; }
}
/// <summary>
/// If set, then dependencies will be found. Otherwise, only Primary references will be
/// resolved.
///
/// Default is true.
/// </summary>
/// <value></value>
public bool FindDependencies
{
get { return _findDependencies; }
set { _findDependencies = value; }
}
/// <summary>
/// If set, then satellites will be found.
///
/// Default is true.
/// </summary>
/// <value></value>
public bool FindSatellites
{
get { return _findSatellites; }
set { _findSatellites = value; }
}
/// <summary>
/// If set, then serialization assemblies will be found.
///
/// Default is true.
/// </summary>
/// <value></value>
public bool FindSerializationAssemblies
{
get { return _findSerializationAssemblies; }
set { _findSerializationAssemblies = value; }
}
/// <summary>
/// If set, then related files (.pdbs and .xmls) will be found.
///
/// Default is true.
/// </summary>
/// <value></value>
public bool FindRelatedFiles
{
get { return _findRelatedFiles; }
set { _findRelatedFiles = value; }
}
/// <summary>
/// If set, then don't log any messages to the screen.
///
/// Default is false.
/// </summary>
/// <value></value>
public bool Silent
{
get { return _silent; }
set { _silent = value; }
}
/// <summary>
/// The project target framework version.
///
/// Default is empty. which means there will be no filtering for the reference based on their target framework.
/// </summary>
/// <value></value>
public string TargetFrameworkVersion
{
get { return _projectTargetFrameworkAsString; }
set { _projectTargetFrameworkAsString = value; }
}
/// <summary>
/// The target framework moniker we are targeting if any. This is used for logging purposes.
///
/// Default is empty.
/// </summary>
/// <value></value>
public string TargetFrameworkMoniker
{
get { return _targetedFrameworkMoniker; }
set { _targetedFrameworkMoniker = value; }
}
/// <summary>
/// The display name of the target framework moniker, if any. This is only for logging.
/// </summary>
public string TargetFrameworkMonikerDisplayName
{
get;
set;
}
/// <summary>
/// Provide a set of names which if seen in the TargetFrameworkSubset list will cause the ignoring
/// of TargetFrameworkSubsets.
///
/// Full, Complete
/// </summary>
public string[] FullTargetFrameworkSubsetNames
{
get
{
return _fullTargetFrameworkSubsetNames;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "FullTargetFrameworkSubsetNames");
_fullTargetFrameworkSubsetNames = value;
}
}
/// <summary>
/// Name of the target framework profile we are targeting.
/// Eg. Client, Web, or Network
/// </summary>
public string ProfileName
{
get
{
return _profileName;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "profileName");
_profileName = value;
}
}
/// <summary>
/// Set of folders which containd a RedistList directory which represent the full framework for a given client profile.
/// An example would be
/// %programfiles%\reference assemblies\microsoft\framework\v4.0
/// </summary>
public string[] FullFrameworkFolders
{
get
{
return _fullFrameworkFolders;
}
set
{
ErrorUtilities.VerifyThrowArgumentNull(value, "FullFrameworkFolders");
_fullFrameworkFolders = value;
}
}
public bool FailIfNotIncremental { get; set; }
/// <summary>
/// This is a list of all primary references resolved to full paths.
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// string FusionName - the fusion name for this dependency.
/// string ResolvedFrom - the literal search path that this file was resolved from.
/// bool IsRedistRoot - Whether or not this assembly is the representative for an entire redist.
/// 'true' means the assembly is representative of an entire redist and should be indicated as
/// an application dependency in an application manifest.
/// 'false' means the assembly is internal to a redist and should not be part of the
/// application manifest.
/// string Redist - The name (if any) of the redist that contains this assembly.
/// </summary>
[Output]
public ITaskItem[] ResolvedFiles
{
get { return _resolvedFiles; }
}
/// <summary>
/// A list of all n-th order paths-to-dependencies with the following attributes:
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// string FusionName - the fusion name for this dependency.
/// string ResolvedFrom - the literal search path that this file was resolved from.
/// bool IsRedistRoot - Whether or not this assembly is the representative for an entire redist.
/// 'true' means the assembly is representative of an entire redist and should be indicated as
/// an application dependency in an application manifest.
/// 'false' means the assembly is internal to a redist and should not be part of the
/// application manifest.
/// string Redist - The name (if any) of the redist that contains this assembly.
/// Does not include first order primary references--this list is in ResolvedFiles.
/// </summary>
[Output]
public ITaskItem[] ResolvedDependencyFiles
{
get { return _resolvedDependencyFiles; }
}
/// <summary>
/// Related files are files like intellidoc (.XML) and symbols (.PDB) that have the same base
/// name as a reference.
/// bool Primary [always false] - true if this assembly was passed in with Assemblies.
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// </summary>
[Output]
public ITaskItem[] RelatedFiles
{
get { return _relatedFiles; }
}
/// <summary>
/// Any satellite files found. These will be CopyLocal=true iff the reference or dependency
/// that caused this item to exist is CopyLocal=true.
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// string DestinationSubDirectory - the relative destination directory that this file
/// should be copied to. This is mainly for satellites.
/// </summary>
[Output]
public ITaskItem[] SatelliteFiles
{
get { return _satelliteFiles; }
}
/// <summary>
/// Any XML serialization assemblies found. These will be CopyLocal=true iff the reference or dependency
/// that caused this item to exist is CopyLocal=true.
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// </summary>
[Output]
public ITaskItem[] SerializationAssemblyFiles
{
get { return _serializationAssemblyFiles; }
}
/// <summary>
/// Scatter files associated with one of the given assemblies.
/// bool CopyLocal - whether the given reference should be copied to the output directory.
/// </summary>
[Output]