forked from dotnet/msbuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ToolLocationHelper.cs
4021 lines (3519 loc) · 225 KB
/
ToolLocationHelper.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
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Build.Shared;
#if FEATURE_WIN32_REGISTRY
using Microsoft.Win32;
#endif
using FrameworkNameVersioning = System.Runtime.Versioning.FrameworkName;
using UtilitiesDotNetFrameworkArchitecture = Microsoft.Build.Utilities.DotNetFrameworkArchitecture;
using SharedDotNetFrameworkArchitecture = Microsoft.Build.Shared.DotNetFrameworkArchitecture;
using Microsoft.Build.Shared.FileSystem;
using Microsoft.Build.Tasks.AssemblyFoldersFromConfig;
namespace Microsoft.Build.Utilities
{
/// <summary>
/// Used to specify the targeted version of the .NET Framework for some methods of ToolLocationHelper.
/// </summary>
public enum TargetDotNetFrameworkVersion
{
/// <summary>
/// version 1.1
/// </summary>
Version11 = 0,
/// <summary>
/// version 2.0
/// </summary>
Version20 = 1,
/// <summary>
/// version 3.0
/// </summary>
Version30 = 2,
/// <summary>
/// version 3.5
/// </summary>
Version35 = 3,
/// <summary>
/// version 4.0
/// </summary>
Version40 = 4,
/// <summary>
/// version 4.5
/// </summary>
Version45 = 5,
/// <summary>
/// version 4.5.1
/// </summary>
Version451 = 6,
/// <summary>
/// version 4.6
/// </summary>
Version46 = 7,
/// <summary>
/// version 4.6.1
/// </summary>
Version461 = 8,
/// <summary>
/// version 4.5.2. Enum is out of order because it was shipped out of band from a Visual Studio update
/// without a corresponding SDK release.
/// </summary>
Version452 = 9,
/// <summary>
/// version 4.6.2
/// </summary>
Version462 = 10,
/// <summary>
/// version 4.7
/// </summary>
Version47 = 11,
/// <summary>
/// version 4.7.1
/// </summary>
Version471 = 12,
/// <summary>
/// version 4.7.2
/// </summary>
Version472 = 13,
/// <summary>
/// version 4.8
/// </summary>
Version48 = 14,
/// <summary>
/// The latest version available at the time of major release. This
/// value should not be updated in minor releases as it could be a
/// breaking change. Use 'Latest' if possible, but note the
/// compatibility implications.
/// </summary>
VersionLatest = Version48,
/// <summary>
/// Sentinel value for the latest version that this version of MSBuild is aware of. Similar
/// to VersionLatest except the compiled value in the calling application will not need to
/// change for the update in MSBuild to be used.
/// </summary>
/// <remarks>
/// This value was introduced in Visual Studio 15.1. It is incompatible with previous
/// versions of MSBuild.
/// </remarks>
Latest = 9999
}
/// <summary>
/// Used to specify the version of Visual Studio from which to select associated
/// tools for some methods of ToolLocationHelper
/// </summary>
public enum VisualStudioVersion
{
/// <summary>
/// Visual Studio 2010 (Dev10) and SP1
/// </summary>
Version100,
/// <summary>
/// Visual Studio 2012 (Dev11)
/// </summary>
Version110,
/// <summary>
/// Visual Studio 2013 (Dev12)
/// </summary>
Version120,
/// <summary>
/// Visual Studio 2015 (Dev14)
/// </summary>
Version140,
/// <summary>
/// Visual Studio 2017 (Dev15)
/// </summary>
Version150,
/// <summary>
/// Visual Studio 2019 (Dev16)
/// </summary>
Version160,
/// <summary>
/// Visual Studio 2022 (Dev17)
/// </summary>
Version170,
// keep this up-to-date; always point to the last entry.
/// <summary>
/// The latest version available at the time of release
/// </summary>
VersionLatest = Version170
}
/// <summary>
/// Used to specify the targeted bitness of the .NET Framework for some methods of ToolLocationHelper
/// </summary>
public enum DotNetFrameworkArchitecture
{
/// <summary>
/// Indicates the .NET Framework that is currently being run under.
/// </summary>
Current = 0,
/// <summary>
/// Indicates the 32-bit .NET Framework
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Bitness", Justification = "Bitness is a reasonable term")]
Bitness32 = 1,
/// <summary>
/// Indicates the 64-bit .NET Framework
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Bitness", Justification = "Bitness is a reasonable term")]
Bitness64 = 2
}
/// <summary>
/// ToolLocationHelper provides utility methods for locating .NET Framework and .NET Framework SDK directories and files.
/// NOTE: All public methods of this class are available to MSBuild projects for use in functions - they must be safe for
/// use during project evaluation.
/// </summary>
public static class ToolLocationHelper
{
/// <summary>
/// Cache the results of reading the redist list so that we do not have to read the redist list over and over again to get the chains.
/// </summary>
private static Dictionary<string, string> s_chainedReferenceAssemblyPath;
/// <summary>
/// Lock object to synchronize chainedReferenceAssemblyPath dictionary
/// </summary>
private static readonly object s_locker = new object();
/// <summary>
/// Cache the results of calling the GetPathToReferenceAssemblies so that we do not recalculate it every time we call the method
/// </summary>
private static Dictionary<string, IList<string>> s_cachedReferenceAssemblyPaths;
/// <summary>
/// Cache the frameworkName of the highest version of a framework given its root path and identifier.
/// This is to optimize calls to GetHighestVersionOfTargetFramework
/// </summary>
private static Dictionary<string, FrameworkNameVersioning> s_cachedHighestFrameworkNameForTargetFrameworkIdentifier;
/// <summary>
/// Cache the sdk structure as found by enumerating the disk and registry.
/// </summary>
private static Dictionary<string, IEnumerable<TargetPlatformSDK>> s_cachedTargetPlatforms;
/// <summary>
/// Cache new style extension sdks that we've enumerated
/// </summary>
private static Dictionary<string, TargetPlatformSDK> s_cachedExtensionSdks;
/// <summary>
/// Cache the display name for the TFM/FrameworkName, keyed by the target framework directory.
/// This is generated by the "Name" attribute on the root tag of the primary matching redist list.
/// Value is never an empty string or null: a name will be synthesized if necessary.
/// </summary>
private static Dictionary<string, string> s_cachedTargetFrameworkDisplayNames;
/// <summary>
/// Cache the set of target platform references for a particular combination of inputs. For legacy
/// target platforms, this is just grabbing all winmds from the References\CommonConfiguration\Neutral
/// folder; for OneCore-based platforms, this involves reading the list from Platform.xml and synthesizing
/// the locations.
/// </summary>
private static Dictionary<string, string[]> s_cachedTargetPlatformReferences;
/// <summary>
/// Cache the set of extension Sdk references for a particular combination of inputs.
/// </summary>
private static Dictionary<string, string[]> s_cachedExtensionSdkReferences;
/// <summary>
/// Cache the list of supported frameworks
/// </summary>
private static List<string> s_targetFrameworkMonikers = null;
/// <summary>
/// Cache the VS Install folders for particular range of VS versions
/// </summary>
private static Dictionary<string, string[]> s_vsInstallFolders;
/// <summary>
/// Character used to separate search paths specified for MSBuildExtensionsPath* in
/// the config file
/// </summary>
private static readonly char[] _separatorForFallbackSearchPaths = MSBuildConstants.SemicolonChar;
private const string retailConfigurationName = "Retail";
private const string neutralArchitectureName = "Neutral";
private const string commonConfigurationFolderName = "CommonConfiguration";
private const string redistFolderName = "Redist";
private const string referencesFolderName = "References";
private const string designTimeFolderName = "DesignTime";
private const string platformsFolderName = "Platforms";
private const string uapDirectoryName = "Windows Kits";
private const string uapRegistryName = "Windows";
private const int uapVersion = 10;
private static readonly char[] s_diskRootSplitChars = MSBuildConstants.SemicolonChar;
/// <summary>
/// Delegate to a method which takes a version enumeration and return a string path
/// </summary>
internal delegate string VersionToPath(TargetDotNetFrameworkVersion version);
#region Public methods
/// <summary>
/// The current ToolsVersion.
/// </summary>
public static string CurrentToolsVersion => MSBuildConstants.CurrentToolsVersion;
#if FEATURE_WIN32_REGISTRY
/// <summary>
/// Get a sorted list of AssemblyFoldersExInfo which contain information about what directories the 3rd party assemblies are registered under for use during build and design time.
///
/// This method will enumerate the AssemblyFoldersEx registry location and return a list of AssemblyFoldersExInfo in the same order in which
/// they will be searched during both design and build time for reference assemblies.
/// </summary>
/// <param name="registryRoot">The root registry location for the targeted framework. For .NET this is SOFTWARE\MICROSOFT\.NETFramework</param>
/// <param name="targetFrameworkVersion">The targeted framework version (2.0, 3.0, 3.5, 4.0, etc)</param>
/// <param name="registryKeySuffix">The name of the folder (AssemblyFoldersEx) could also be PocketPC\AssemblyFoldersEx, or others</param>
/// <param name="osVersion">Components may declare Min and Max OSVersions in the registry this value can be used filter directories returned based on whether or not the osversion is bounded by the Min and Max versions declared by the component. If this value is blank or null no filtering is done</param>
/// <param name="platform">Components may declare platform guids in the registry this can be used to return only directories which have a certain platform guid. If this value is blank or null no filtering is done</param>
/// <param name="targetProcessorArchitecture">What processor architecture is being targeted. This determines which registry hives are searched in what order.
/// On a 64 bit operating system we do the following
/// If you are targeting 64 bit (target x64 or ia64)
/// Add in the 64 bit hive first
/// Add in the 32 bit hive second
/// If you are not targeting a 64 bit
/// Add in the 32 bit hive first
/// Add in the 64 bit hive second
/// On a 32 bit machine we only add in the 32 bit hive.
/// </param>
/// <returns>List of AssemblyFoldersExInfo</returns>
public static IList<AssemblyFoldersExInfo> GetAssemblyFoldersExInfo(string registryRoot, string targetFrameworkVersion, string registryKeySuffix, string osVersion, string platform, System.Reflection.ProcessorArchitecture targetProcessorArchitecture)
{
ErrorUtilities.VerifyThrowArgumentLength(registryRoot, nameof(registryRoot));
ErrorUtilities.VerifyThrowArgumentLength(registryKeySuffix, nameof(registryKeySuffix));
ErrorUtilities.VerifyThrowArgumentLength(targetFrameworkVersion, nameof(targetFrameworkVersion));
AssemblyFoldersEx assemblyFoldersEx = new AssemblyFoldersEx(registryRoot, targetFrameworkVersion, registryKeySuffix, osVersion, platform, new GetRegistrySubKeyNames(RegistryHelper.GetSubKeyNames), new GetRegistrySubKeyDefaultValue(RegistryHelper.GetDefaultValue), targetProcessorArchitecture, new OpenBaseKey(RegistryHelper.OpenBaseKey));
var assemblyFolders = new List<AssemblyFoldersExInfo>();
assemblyFolders.AddRange(assemblyFoldersEx);
return assemblyFolders;
}
#endif
/// <summary>
/// Get a sorted list of AssemblyFoldersFromConfigInfo which contain information about what directories the 3rd party assemblies are registered under for use during build and design time.
///
/// This method will read the specified configuration file and enumerate the and return a list of AssemblyFoldersFromConfigInfo in the same order in which
/// they will be searched during both design and build time for reference assemblies.
/// </summary>
/// <param name="configFile">Full path to the Assembly Folders config file.</param>
/// <param name="targetFrameworkVersion">The targeted framework version (2.0, 3.0, 3.5, 4.0, etc).</param>
/// <param name="targetProcessorArchitecture">What processor architecture is being targeted. This determines which registry hives are searched in what order.
/// On a 64 bit operating system we do the following
/// If you are targeting 64 bit (target x64 or ia64)
/// Add in the 64 bit assembly folders first
/// Add in the 32 bit assembly folders second
/// If you are not targeting a 64 bit
/// Add in the 32 bit assembly folders first
/// Add in the 64 bit assembly folders second
/// On a 32 bit machine we only add in the 32 bit assembly folders.
/// </param>
/// <returns>List of AssemblyFoldersFromConfigInfo</returns>
public static IList<AssemblyFoldersFromConfigInfo> GetAssemblyFoldersFromConfigInfo(string configFile, string targetFrameworkVersion, System.Reflection.ProcessorArchitecture targetProcessorArchitecture)
{
ErrorUtilities.VerifyThrowArgumentLength(configFile, nameof(configFile));
ErrorUtilities.VerifyThrowArgumentLength(targetFrameworkVersion, nameof(targetFrameworkVersion));
var assemblyFoldersInfos = new AssemblyFoldersFromConfig(configFile, targetFrameworkVersion, targetProcessorArchitecture);
return assemblyFoldersInfos.ToList();
}
/// <summary>
/// Get a list of SDK's installed on the machine for a given target platform
/// </summary>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their location. K:SDKName V:SDK installation location</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IDictionary<string, string> GetPlatformExtensionSDKLocations(string targetPlatformIdentifier, Version targetPlatformVersion)
=> GetPlatformExtensionSDKLocations(null, null, targetPlatformIdentifier, targetPlatformVersion);
/// <summary>
/// Get a list of SDK's installed on the machine for a given target platform
/// </summary>
/// <param name="diskRoots">Array of disk locations to search for sdks</param>
/// <param name="registryRoot">Root registry location to look for sdks</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their location. K:SDKName V:SDK installation location</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IDictionary<string, string> GetPlatformExtensionSDKLocations(string[] diskRoots, string registryRoot, string targetPlatformIdentifier, Version targetPlatformVersion)
=> GetPlatformExtensionSDKLocations(diskRoots, null, registryRoot, targetPlatformIdentifier, targetPlatformVersion);
/// <summary>
/// Get a list of SDK's installed on the machine for a given target platform
/// </summary>
/// <param name="diskRoots">Array of disk locations to search for sdks</param>
/// <param name="extensionDiskRoots">New style extension SDK roots</param>
/// <param name="registryRoot">Root registry location to look for sdks</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their location. K:SDKName V:SDK installation location</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IDictionary<string, string> GetPlatformExtensionSDKLocations(string[] diskRoots, string[] extensionDiskRoots, string registryRoot, string targetPlatformIdentifier, Version targetPlatformVersion)
{
var extensionSDKs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
IEnumerable<TargetPlatformSDK> targetPlatformMonikers = GetTargetPlatformMonikers(diskRoots, extensionDiskRoots, registryRoot, targetPlatformIdentifier, targetPlatformVersion);
foreach (TargetPlatformSDK moniker in targetPlatformMonikers)
{
foreach (KeyValuePair<string, string> extension in moniker.ExtensionSDKs)
{
extensionSDKs[extension.Key] = extension.Value;
}
}
return extensionSDKs;
}
/// <summary>
/// Get a list of SDK's installed on the machine for a given target platform
/// </summary>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their tuples containing (location, platform version).</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Casing kept to maintain consistency with existing APIs")]
public static IDictionary<string, Tuple<string, string>> GetPlatformExtensionSDKLocationsAndVersions(string targetPlatformIdentifier, Version targetPlatformVersion)
=> GetPlatformExtensionSDKLocationsAndVersions(null, null, targetPlatformIdentifier, targetPlatformVersion);
/// <summary>
/// Set of installed SDKs and their location and platform versions
/// </summary>
/// <param name="diskRoots">Array of disk locations to search for sdks</param>
/// <param name="registryRoot">Root registry location to look for sdks</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their tuples containing (location, platform version).</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Casing kept to maintain consistency with existing APIs")]
public static IDictionary<string, Tuple<string, string>> GetPlatformExtensionSDKLocationsAndVersions(string[] diskRoots, string registryRoot, string targetPlatformIdentifier, Version targetPlatformVersion)
=> GetPlatformExtensionSDKLocationsAndVersions(diskRoots, null, registryRoot, targetPlatformIdentifier, targetPlatformVersion);
/// <summary>
/// Set of installed SDKs and their location and platform versions
/// </summary>
/// <param name="diskRoots">Array of disk locations to search for sdks</param>
/// <param name="multiPlatformDiskRoots">Array of disk locations to search for SDKs that target multiple versions</param>
/// <param name="registryRoot">Root registry location to look for sdks</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>IDictionary of installed SDKS and their tuples containing (location, platform version). Version may be null if the SDK targets multiple versions.</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Casing kept to maintain consistency with existing APIs")]
public static IDictionary<string, Tuple<string, string>> GetPlatformExtensionSDKLocationsAndVersions(string[] diskRoots, string[] multiPlatformDiskRoots, string registryRoot, string targetPlatformIdentifier, Version targetPlatformVersion)
{
var extensionSDKsAndVersions = new Dictionary<string, Tuple<string, string>>(StringComparer.OrdinalIgnoreCase);
IEnumerable<TargetPlatformSDK> targetPlatformMonikers = GetTargetPlatformMonikers(diskRoots, multiPlatformDiskRoots, registryRoot, targetPlatformIdentifier, targetPlatformVersion);
foreach (TargetPlatformSDK moniker in targetPlatformMonikers)
{
foreach (KeyValuePair<string, string> extension in moniker.ExtensionSDKs)
{
extensionSDKsAndVersions[extension.Key] = Tuple.Create<string, string>(extension.Value, moniker.TargetPlatformVersion.ToString());
}
}
return extensionSDKsAndVersions;
}
/// <summary>
/// Get target platform monikers used to extract ESDK information in the methods GetPlatformExtensionSDKLocationsAndVersions and GetPlatformExtensionSDKLocations
/// </summary>
private static IEnumerable<TargetPlatformSDK> GetTargetPlatformMonikers(string[] diskRoots, string[] extensionDiskRoots, string registryRoot, string targetPlatformIdentifier, Version targetPlatformVersion)
{
ErrorUtilities.VerifyThrowArgumentLength(targetPlatformIdentifier, nameof(targetPlatformIdentifier));
ErrorUtilities.VerifyThrowArgumentNull(targetPlatformVersion, nameof(targetPlatformVersion));
string targetPlatformVersionString = targetPlatformVersion.ToString();
ErrorUtilities.DebugTraceMessage("GetPlatformExtensionSDKLocations", "Calling with TargetPlatformIdentifier:'{0}' and TargetPlatformVersion: '{1}'", targetPlatformIdentifier, targetPlatformVersionString);
IEnumerable<TargetPlatformSDK> targetPlatformSDKs = RetrieveTargetPlatformList(diskRoots, extensionDiskRoots, registryRoot);
return targetPlatformSDKs
.Where<TargetPlatformSDK>(platformSDK =>
string.IsNullOrEmpty(platformSDK.TargetPlatformIdentifier)
||
(
platformSDK.TargetPlatformIdentifier.Equals(targetPlatformIdentifier, StringComparison.OrdinalIgnoreCase)
&& platformSDK.TargetPlatformVersion <= targetPlatformVersion
) || platformSDK.ContainsPlatform(targetPlatformIdentifier, targetPlatformVersionString))
.OrderBy<TargetPlatformSDK, Version>(platform => platform.TargetPlatformVersion);
}
/// <summary>
/// Given an SDKName, targetPlatformIdentifier and TargetPlatformVersion search the default sdk locations for the passed in sdk name.
/// The format of the sdk moniker is SDKName, Version=X.X
/// </summary>
/// <param name="sdkMoniker">Name of the SDK to determine the installation location for.</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <returns>Location of the SDK if it is found, empty string if it could not be found</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, Version targetPlatformVersion)
=> GetPlatformExtensionSDKLocation(sdkMoniker, targetPlatformIdentifier, targetPlatformVersion, null, null);
/// <summary>
/// Given an SDKName, targetPlatformIdentifier and TargetPlatformVersion search the default sdk locations for the passed in sdk name.
/// The format of the sdk moniker is SDKName, Version=X.X
/// </summary>
/// <param name="sdkMoniker">Name of the SDK to determine the installation location for.</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <param name="diskRoots">List of disk roots to search for sdks within</param>
/// <param name="registryRoot">Registry root to look for sdks within</param>
/// <returns>Location of the SDK if it is found, empty string if it could not be found</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, Version targetPlatformVersion, string[] diskRoots, string registryRoot)
=> GetPlatformExtensionSDKLocation(sdkMoniker, targetPlatformIdentifier, targetPlatformVersion, diskRoots, null, registryRoot);
/// <summary>
/// Given an SDKName, targetPlatformIdentifier and TargetPlatformVersion search the default sdk locations for the passed in sdk name.
/// The format of the sdk moniker is SDKName, Version=X.X
/// </summary>
/// <param name="sdkMoniker">Name of the SDK to determine the installation location for.</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <param name="diskRoots">List of disk roots to search for sdks within</param>
/// <param name="extensionDiskRoots">List of disk roots to look for manifest driven extension sdks</param>
/// <param name="registryRoot">Registry root to look for sdks within</param>
/// <returns>Location of the SDK if it is found, empty string if it could not be found</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, Version targetPlatformVersion, string[] diskRoots, string[] extensionDiskRoots, string registryRoot)
{
ErrorUtilities.VerifyThrowArgumentLength(targetPlatformIdentifier, nameof(targetPlatformIdentifier));
ErrorUtilities.VerifyThrowArgumentNull(targetPlatformVersion, nameof(targetPlatformVersion));
ErrorUtilities.VerifyThrowArgumentLength(sdkMoniker, nameof(sdkMoniker));
IEnumerable<TargetPlatformSDK> targetPlatforms = RetrieveTargetPlatformList(diskRoots, extensionDiskRoots, registryRoot);
var targetPlatformMoniker = targetPlatforms.Where<TargetPlatformSDK>(
platform =>
(
string.IsNullOrEmpty(platform.TargetPlatformIdentifier)
||
(platform.TargetPlatformIdentifier.Equals(targetPlatformIdentifier, StringComparison.OrdinalIgnoreCase)
&& platform.TargetPlatformVersion <= targetPlatformVersion)
)
&& platform.ExtensionSDKs.ContainsKey(sdkMoniker))
.OrderByDescending<TargetPlatformSDK, Version>(platform => platform.TargetPlatformVersion)
.DefaultIfEmpty(null).FirstOrDefault<TargetPlatformSDK>();
if (targetPlatformMoniker != null)
{
return targetPlatformMoniker.ExtensionSDKs[sdkMoniker];
}
else
{
return string.Empty;
}
}
/// <summary>
/// Given an SDK moniker and the targeted platform get the path to the SDK root if it exists.
/// </summary>
/// <param name="sdkMoniker">Moniker for the sdk</param>
/// <param name="targetPlatformIdentifier">Identifier for the platform</param>
/// <param name="targetPlatformVersion">Version of the platform</param>
/// <returns>A full path to the sdk root if the sdk exists in the targeted platform or an empty string if it does not exist.</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, string targetPlatformVersion)
=> GetPlatformExtensionSDKLocation(sdkMoniker, targetPlatformIdentifier, targetPlatformVersion, null, null);
/// <summary>
/// Given an SDKName, targetPlatformIdentifier and TargetPlatformVersion search the default sdk locations for the passed in sdk name.
/// The format of the sdk moniker is SDKName, Version=X.X
/// </summary>
/// <param name="sdkMoniker">Name of the SDK to determine the installation location for.</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <param name="diskRoots">List of disk roots to search for sdks within</param>
/// <param name="registryRoot">Registry root to look for sdks within</param>
/// <returns>Location of the SDK if it is found, empty string if it could not be found</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, string targetPlatformVersion, string diskRoots, string registryRoot)
=> GetPlatformExtensionSDKLocation(sdkMoniker, targetPlatformIdentifier, targetPlatformVersion, diskRoots, null, registryRoot);
/// <summary>
/// Given an SDKName, targetPlatformIdentifier and TargetPlatformVersion search the default sdk locations for the passed in sdk name.
/// The format of the sdk moniker is SDKName, Version=X.X
/// </summary>
/// <param name="sdkMoniker">Name of the SDK to determine the installation location for.</param>
/// <param name="targetPlatformIdentifier">Targeted platform to find SDKs for</param>
/// <param name="targetPlatformVersion">Targeted platform version to find SDKs for</param>
/// <param name="diskRoots">List of disk roots to search for sdks within</param>
/// <param name="extensionDiskRoots">List of disk roots to look for manifest driven extension sdks</param>
/// <param name="registryRoot">Registry root to look for sdks within</param>
/// <returns>Location of the SDK if it is found, empty string if it could not be found</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static string GetPlatformExtensionSDKLocation(string sdkMoniker, string targetPlatformIdentifier, string targetPlatformVersion, string diskRoots, string extensionDiskRoots, string registryRoot)
{
ErrorUtilities.VerifyThrowArgumentNull(targetPlatformVersion, nameof(targetPlatformVersion));
string[] sdkDiskRoots = null;
if (!string.IsNullOrEmpty(diskRoots))
{
sdkDiskRoots = diskRoots.Split(s_diskRootSplitChars, StringSplitOptions.RemoveEmptyEntries);
}
string[] extensionSdkDiskRoots = null;
if (!string.IsNullOrEmpty(extensionDiskRoots))
{
extensionSdkDiskRoots = extensionDiskRoots.Split(s_diskRootSplitChars, StringSplitOptions.RemoveEmptyEntries);
}
string sdkLocation = string.Empty;
if (Version.TryParse(targetPlatformVersion, out Version platformVersion))
{
sdkLocation = GetPlatformExtensionSDKLocation(sdkMoniker, targetPlatformIdentifier, platformVersion, sdkDiskRoots, extensionSdkDiskRoots, registryRoot);
}
return sdkLocation;
}
/// <summary>
/// Gets a dictionary containing a collection of extension SDKs and filter it based on the target platform version
/// if max platform version isn't set in the extension sdk manifest, add the extension sdk to the filtered list
/// </summary>
/// <param name="targetPlatformVersion"></param>
/// <param name="extensionSdks"></param>
/// <returns>A IDictionary collection of filtered extension SDKs</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Not worth breaking customers")]
public static IDictionary<string, string> FilterPlatformExtensionSDKs(Version targetPlatformVersion, IDictionary<string, string> extensionSdks)
{
var filteredExtensionSdks = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> sdk in extensionSdks)
{
ExtensionSDK extensionSDK = new ExtensionSDK(sdk.Key, sdk.Value);
// filter based on platform version - let pass if not in manifest or parameter
if (extensionSDK.MaxPlatformVersion == null || targetPlatformVersion == null || extensionSDK.MaxPlatformVersion >= targetPlatformVersion)
{
filteredExtensionSdks.Add(sdk.Key, sdk.Value);
}
}
return filteredExtensionSdks;
}
/// <summary>
/// Get the list of SDK folders which contains the references for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK</param>
/// <returns>A list of folders in the order which they should be used when looking for references in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKReferenceFolders(string sdkRoot) => GetSDKReferenceFolders(sdkRoot, retailConfigurationName, neutralArchitectureName);
/// <summary>
/// Get the list of SDK folders which contains the references for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK</param>
/// <param name="targetConfiguration">The configuration the SDK is targeting. This should be Debug or Retail</param>
/// <param name="targetArchitecture">The architecture the SDK is targeting</param>
/// <returns>A list of folders in the order which they should be used when looking for references in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKReferenceFolders(string sdkRoot, string targetConfiguration, string targetArchitecture)
{
ErrorUtilities.VerifyThrowArgumentLength(sdkRoot, nameof(sdkRoot));
ErrorUtilities.VerifyThrowArgumentLength(targetConfiguration, nameof(targetConfiguration));
ErrorUtilities.VerifyThrowArgumentLength(targetArchitecture, nameof(targetArchitecture));
var referenceDirectories = new List<string>(4);
string legacyWindowsMetadataLocation = Path.Combine(sdkRoot, "Windows Metadata");
if (FileUtilities.DirectoryExistsNoThrow(legacyWindowsMetadataLocation))
{
legacyWindowsMetadataLocation = FileUtilities.EnsureTrailingSlash(legacyWindowsMetadataLocation);
referenceDirectories.Add(legacyWindowsMetadataLocation);
}
AddSDKPaths(sdkRoot, referencesFolderName, targetConfiguration, targetArchitecture, referenceDirectories);
return referenceDirectories;
}
/// <summary>
/// Add the set of paths for where sdk files should be found. Where <folderType> is redist, references, designtime
/// </summary>
private static void AddSDKPaths(string sdkRoot, string folderName, string targetConfiguration, string targetArchitecture, List<string> directories)
{
targetArchitecture = RemapSdkArchitecture(targetArchitecture);
// <SDKROOT>\<folderType>\Debug\X86
AddSDKPath(sdkRoot, folderName, targetConfiguration, targetArchitecture, directories);
if (!neutralArchitectureName.Equals(targetArchitecture, StringComparison.OrdinalIgnoreCase))
{
// <SDKROOT>\<folderType>\Debug\Neutral
AddSDKPath(sdkRoot, folderName, targetConfiguration, neutralArchitectureName, directories);
}
// <SDKROOT>\<folderType>\CommonConfiguration\x86
AddSDKPath(sdkRoot, folderName, commonConfigurationFolderName, targetArchitecture, directories);
if (!neutralArchitectureName.Equals(targetArchitecture, StringComparison.OrdinalIgnoreCase))
{
// <SDKROOT>\<folderType>\CommonConfiguration\Neutral
AddSDKPath(sdkRoot, folderName, commonConfigurationFolderName, neutralArchitectureName, directories);
}
}
/// <summary>
/// Get the list of SDK folders which contains the redist files for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK must contain a redist folder</param>
/// <returns>A list of folders in the order which they should be used when looking for redist files in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKRedistFolders(string sdkRoot) => GetSDKRedistFolders(sdkRoot, retailConfigurationName, neutralArchitectureName);
/// <summary>
/// Get the list of SDK folders which contains the redist files for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK must contain a redist folder</param>
/// <param name="targetConfiguration">The configuration the SDK is targeting. This should be Debug or Retail</param>
/// <param name="targetArchitecture">The architecture the SDK is targeting</param>
/// <returns>A list of folders in the order which they should be used when looking for redist files in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKRedistFolders(string sdkRoot, string targetConfiguration, string targetArchitecture)
{
ErrorUtilities.VerifyThrowArgumentLength(sdkRoot, nameof(sdkRoot));
ErrorUtilities.VerifyThrowArgumentLength(targetConfiguration, nameof(targetConfiguration));
ErrorUtilities.VerifyThrowArgumentLength(targetArchitecture, nameof(targetArchitecture));
var redistDirectories = new List<string>(4);
AddSDKPaths(sdkRoot, redistFolderName, targetConfiguration, targetArchitecture, redistDirectories);
return redistDirectories;
}
/// <summary>
/// Get the list of SDK folders which contains the designtime files for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK must contain a Designtime folder</param>
/// <returns>A list of folders in the order which they should be used when looking for DesignTime files in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKDesignTimeFolders(string sdkRoot) => GetSDKDesignTimeFolders(sdkRoot, retailConfigurationName, neutralArchitectureName);
/// <summary>
/// Get the list of SDK folders which contains the DesignTime files for the sdk at the sdkRoot provided
/// in the order in which they should be searched for references.
/// </summary>
/// <param name="sdkRoot">Root folder for the SDK must contain a DesignTime folder</param>
/// <param name="targetConfiguration">The configuration the SDK is targeting. This should be Debug or Retail</param>
/// <param name="targetArchitecture">The architecture the SDK is targeting</param>
/// <returns>A list of folders in the order which they should be used when looking for DesignTime files in the SDK</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDK", Justification = "Shipped this way in Dev11 Beta (go-live)")]
public static IList<string> GetSDKDesignTimeFolders(string sdkRoot, string targetConfiguration, string targetArchitecture)
{
ErrorUtilities.VerifyThrowArgumentLength(sdkRoot, nameof(sdkRoot));
ErrorUtilities.VerifyThrowArgumentLength(targetConfiguration, nameof(targetConfiguration));
ErrorUtilities.VerifyThrowArgumentLength(targetArchitecture, nameof(targetArchitecture));
var designTimeDirectories = new List<string>(4);
AddSDKPaths(sdkRoot, designTimeFolderName, targetConfiguration, targetArchitecture, designTimeDirectories);
return designTimeDirectories;
}
/// <summary>
/// Get a list target platform sdks on the machine.
/// </summary>
/// <returns>List of Target Platform SDKs, Item1: TargetPlatformName Item2: Version of SDK Item3: Path to sdk root</returns>
public static IList<TargetPlatformSDK> GetTargetPlatformSdks() => GetTargetPlatformSdks(null, null);
/// <summary>
/// Get a list target platform sdks on the machine.
/// </summary>
/// <param name="diskRoots">List of disk locations to search for platform sdks</param>
/// <param name="registryRoot">Registry root location to look for platform sdks</param>
/// <returns>List of Target Platform SDKs</returns>
public static IList<TargetPlatformSDK> GetTargetPlatformSdks(string[] diskRoots, string registryRoot)
{
IEnumerable<TargetPlatformSDK> targetPlatforms = RetrieveTargetPlatformList(diskRoots, null, registryRoot);
return targetPlatforms.Where<TargetPlatformSDK>(platform => platform.Path != null).ToList<TargetPlatformSDK>();
}
/// <summary>
/// Filter list of platform sdks based on minimum OS and VS versions
/// </summary>
/// <param name="targetPlatformSdkList">List of platform sdks</param>
/// <param name="osVersion">Operating System version. Pass null to not filter based on this parameter</param>
/// <param name="vsVersion">Visual Studio version. Pass null not to filter based on this parameter</param>
/// <returns>List of Target Platform SDKs</returns>
public static IList<TargetPlatformSDK> FilterTargetPlatformSdks(IList<TargetPlatformSDK> targetPlatformSdkList, Version osVersion, Version vsVersion)
{
var filteredTargetPlatformSdkList = new List<TargetPlatformSDK>();
foreach (TargetPlatformSDK targetPlatformSdk in targetPlatformSdkList)
{
if (
(targetPlatformSdk.MinOSVersion == null || osVersion == null || targetPlatformSdk.MinOSVersion <= osVersion) && // filter based on OS version - let pass if not in manifest or parameter
(targetPlatformSdk.MinVSVersion == null || vsVersion == null || targetPlatformSdk.MinVSVersion <= vsVersion) // filter based on VS version - let pass if not in manifest or parameter
)
{
filteredTargetPlatformSdkList.Add(targetPlatformSdk);
}
}
return filteredTargetPlatformSdkList;
}
/// <summary>
/// Get the location of the target platform SDK props file for a given {SDKI, SDKV, TPI, TPMinV, TPV} combination.
/// </summary>
/// <param name="sdkIdentifier">The OneCore SDK identifier that defines OnceCore SDK root</param>
/// <param name="sdkVersion">The verision of the OneCore SDK</param>
/// <param name="targetPlatformIdentifier">Identifier for the targeted platform</param>
/// <param name="targetPlatformMinVersion">The min version of the targeted platform</param>
/// <param name="targetPlatformVersion">The version of the targeted platform</param>
/// <returns>Location of the target platform SDK props file without .props filename</returns>
public static string GetPlatformSDKPropsFileLocation(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion)
=> GetPlatformSDKPropsFileLocation(sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, null, null);
/// <summary>
/// Get the location of the target platform SDK props file for a given {SDKI, SDKV, TPI, TPMinV, TPV} combination.
/// </summary>
/// <param name="sdkIdentifier">The OneCore SDK identifier that defines OnceCore SDK root</param>
/// <param name="sdkVersion">The verision of the OneCore SDK</param>
/// <param name="targetPlatformIdentifier">Identifier for the targeted platform</param>
/// <param name="targetPlatformMinVersion">The min version of the targeted platform</param>
/// <param name="targetPlatformVersion">The version of the targeted platform</param>
/// <param name="diskRoots">List of disk roots to search for sdks within</param>
/// <param name="registryRoot">Registry root to look for sdks within</param>
/// <returns>Location of the target platform SDK props file without .props filename</returns>
public static string GetPlatformSDKPropsFileLocation(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion, string diskRoots, string registryRoot)
{
ErrorUtilities.VerifyThrowArgumentLength(targetPlatformIdentifier, nameof(targetPlatformIdentifier));
ErrorUtilities.VerifyThrowArgumentLength(targetPlatformVersion, nameof(targetPlatformVersion));
string propsFileLocation;
try
{
// e.g. C:\Program Files (x86)\Windows Kits\8.2
string sdkRoot = GetPlatformSDKLocation(targetPlatformIdentifier, targetPlatformVersion, diskRoots, registryRoot);
if (!string.IsNullOrEmpty(sdkRoot))
{
// In the old SDK world, it is e.g. C:\Program Files (x86)\Windows Kits\8.2\DesignTime\CommonConfiguration\Neutral
// In OneCore SDK world, it is e.g. C:\Program Files (x86)\Windows Kits\10.0\DesignTime\CommonConfiguration\Neutral\UAP\0.8.0.0
if (string.IsNullOrEmpty(sdkIdentifier))
{
propsFileLocation = Path.Combine(sdkRoot, designTimeFolderName, commonConfigurationFolderName, neutralArchitectureName);
}
else
{
propsFileLocation = Path.Combine(sdkRoot, designTimeFolderName, commonConfigurationFolderName, neutralArchitectureName, targetPlatformIdentifier, targetPlatformVersion);
}
if (FileSystems.Default.DirectoryExists(propsFileLocation))
{
return propsFileLocation;
}
else
{
ErrorUtilities.DebugTraceMessage("GetPlatformSDKPropsFileLocation", "Target platform props file location '{0}' did not exist.", propsFileLocation);
}
}
else
{
ErrorUtilities.DebugTraceMessage("GetPlatformSDKPropsFileLocation", "Could not find root SDK location for SDKI = '{0}', SDKV = '{1}'", sdkIdentifier, sdkVersion);
}
}
catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e))
{
ErrorUtilities.DebugTraceMessage("GetPlatformSDKPropsFileLocation", "Encountered exception trying to get the SDK props file Location : {0}", e.Message);
}
return null;
}
/// <summary>
/// Gathers the set of platform winmds for a particular {SDKI, SDKV, TPI, TPMinV, TPV} combination
/// </summary>
public static string[] GetTargetPlatformReferences(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion)
=> GetTargetPlatformReferences(sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, null, null);
/// <summary>
/// Gathers the set of platform winmds for a particular {SDKI, SDKV, TPI, TPMinV, TPV} combination
/// </summary>
public static string[] GetTargetPlatformReferences(string sdkIdentifier, string sdkVersion, string targetPlatformIdentifier, string targetPlatformMinVersion, string targetPlatformVersion, string diskRoots, string registryRoot)
{
lock (s_locker)
{
if (s_cachedTargetPlatformReferences == null)
{
s_cachedTargetPlatformReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
string cacheKey = string.Join("|", sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
if (s_cachedTargetPlatformReferences.TryGetValue(cacheKey, out string[] targetPlatformReferences))
{
return targetPlatformReferences;
}
if (string.IsNullOrEmpty(sdkIdentifier) && string.IsNullOrEmpty(sdkVersion))
{
targetPlatformReferences = GetLegacyTargetPlatformReferences(targetPlatformIdentifier, targetPlatformVersion, diskRoots, registryRoot);
}
else
{
targetPlatformReferences = GetTargetPlatformReferencesFromManifest(sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
}
s_cachedTargetPlatformReferences.Add(cacheKey, targetPlatformReferences);
return targetPlatformReferences;
}
}
/// <summary>
/// Gathers the specified extension SDK references for the given target SDK
/// </summary>
/// <param name="extensionSdkMoniker">The moniker is the Name/Version string. Example: "Windows Desktop, Version=10.0.0.1"</param>
/// <param name="targetSdkIdentifier">The target SDK name.</param>
/// <param name="targetSdkVersion">The target SDK version.</param>
/// <param name="diskRoots">The disk roots used to gather installed SDKs.</param>
/// <param name="extensionDiskRoots">The disk roots used to gather installed extension SDKs.</param>
/// <param name="registryRoot">The registry root used to gather installed extension SDKs.</param>
public static string[] GetPlatformOrFrameworkExtensionSdkReferences(string extensionSdkMoniker, string targetSdkIdentifier, string targetSdkVersion, string diskRoots, string extensionDiskRoots, string registryRoot)
=> GetPlatformOrFrameworkExtensionSdkReferences(
extensionSdkMoniker,
targetSdkIdentifier,
targetSdkVersion,
diskRoots,
extensionDiskRoots,
registryRoot,
targetPlatformIdentifier: null,
targetPlatformVersion: null);
/// <summary>
/// Gathers the specified extension SDK references for the given target SDK
/// </summary>
/// <param name="extensionSdkMoniker">The moniker is the Name/Version string. Example: "Windows Desktop, Version=10.0.0.1"</param>
/// <param name="targetSdkIdentifier">The target SDK name.</param>
/// <param name="targetSdkVersion">The target SDK version.</param>
/// <param name="targetPlatformIdentifier">The target platform name.</param>
/// <param name="targetPlatformVersion">The target platform version.</param>
/// <param name="diskRoots">The disk roots used to gather installed SDKs.</param>
/// <param name="extensionDiskRoots">The disk roots used to gather installed extension SDKs.</param>
/// <param name="registryRoot">The registry root used to gather installed extension SDKs.</param>
public static string[] GetPlatformOrFrameworkExtensionSdkReferences
(
string extensionSdkMoniker,
string targetSdkIdentifier,
string targetSdkVersion,
string diskRoots,
string extensionDiskRoots,
string registryRoot,
string targetPlatformIdentifier,
string targetPlatformVersion
)
{
lock (s_locker)
{
if (s_cachedExtensionSdkReferences == null)
{
s_cachedExtensionSdkReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
string cacheKey = string.Join("|", extensionSdkMoniker, targetSdkIdentifier, targetSdkVersion);
if (s_cachedExtensionSdkReferences.TryGetValue(cacheKey, out string[] extensionSdkReferences))
{
return extensionSdkReferences;
}
TargetPlatformSDK matchingSdk = GetMatchingPlatformSDK(targetSdkIdentifier, targetSdkVersion, diskRoots, extensionDiskRoots, registryRoot);
if (matchingSdk == null)
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find root SDK for SDKI = '{0}', SDKV = '{1}'", targetSdkIdentifier, targetSdkVersion);
}
else
{
string targetSdkPath = matchingSdk.Path;
string platformVersion = GetPlatformVersion(matchingSdk, targetPlatformIdentifier, targetPlatformVersion);
if (matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out string extensionSdkPath)
||
(s_cachedExtensionSdks.TryGetValue(extensionDiskRoots, out matchingSdk)
&& matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out extensionSdkPath)))
{
ExtensionSDK extensionSdk = new ExtensionSDK(extensionSdkMoniker, extensionSdkPath);
if (extensionSdk.SDKType == SDKType.Framework || extensionSdk.SDKType == SDKType.Platform)
{
// We don't want to attempt to gather ApiContract references if the framework isn't explicitly marked as Framework/Platform
extensionSdkReferences = GetApiContractReferences(extensionSdk.ApiContracts, targetSdkPath, platformVersion);
}
}
else
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find matching extension SDK = '{0}'", extensionSdkMoniker);
}
}
s_cachedExtensionSdkReferences.Add(cacheKey, extensionSdkReferences);
return extensionSdkReferences;
}
}
/// <summary>
/// Get platform version string which is used to generate versioned path
/// </summary>