aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2023-01-15 19:17:29 -0600
committerSean Hall <r.sean.hall@gmail.com>2023-01-18 18:10:56 -0600
commitd180bc6df297422f189ffd08a0dd558bfbeba1ca (patch)
tree9eac5847ce2335548232480b0ccb197f5dda23a0
parent853887b4e84df1965794802b7683f3a9aca3e930 (diff)
downloadwix-d180bc6df297422f189ffd08a0dd558bfbeba1ca.tar.gz
wix-d180bc6df297422f189ffd08a0dd558bfbeba1ca.tar.bz2
wix-d180bc6df297422f189ffd08a0dd558bfbeba1ca.zip
Add netfx:DotNetCoreSdkFeatureBandSearch.
7058
-rw-r--r--src/api/wix/WixToolset.Data/WixVersionLabel.cs43
-rw-r--r--src/ext/NetFx/be/detectnetcore.cpp91
-rw-r--r--src/ext/NetFx/be/detectnetcoresdk.cpp99
-rw-r--r--src/ext/NetFx/be/detectnetcoresdkfeatureband.cpp55
-rw-r--r--src/ext/NetFx/be/detectnetcoresdkfeatureband.h9
-rw-r--r--src/ext/NetFx/be/netfxbe.vcxproj4
-rw-r--r--src/ext/NetFx/be/netfxsearch.cpp32
-rw-r--r--src/ext/NetFx/be/netfxsearch.h10
-rw-r--r--src/ext/NetFx/be/precomp.h2
-rw-r--r--src/ext/NetFx/be/runnetcoresearch.cpp102
-rw-r--r--src/ext/NetFx/be/runnetcoresearch.h9
-rw-r--r--src/ext/NetFx/netcoresearch/netcoresearch.cpp327
-rw-r--r--src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest.wxs2
-rw-r--r--src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest_x64.wxs1
-rw-r--r--src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x64.wxs17
-rw-r--r--src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x86.wxs17
-rw-r--r--src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3_Platform.wxi5
-rw-r--r--src/ext/NetFx/wixext/NetFxCompiler.cs190
-rw-r--r--src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkFeatureBandSymbol.cs71
-rw-r--r--src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkSymbol.cs25
-rw-r--r--src/ext/NetFx/wixext/Symbols/NetfxSymbolDefinitions.cs7
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6.0.9_x86.wxs21
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6_Platform.wxi7
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib_x64/NetCore6.0.9_x64.wxs21
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib_x64/WixBA_x64.wxs6
25 files changed, 745 insertions, 428 deletions
diff --git a/src/api/wix/WixToolset.Data/WixVersionLabel.cs b/src/api/wix/WixToolset.Data/WixVersionLabel.cs
deleted file mode 100644
index c4227c49..00000000
--- a/src/api/wix/WixToolset.Data/WixVersionLabel.cs
+++ /dev/null
@@ -1,43 +0,0 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Data
4{
5 using System;
6
7 /// <summary>
8 /// Label in a <c>WixVersion</c>.
9 /// </summary>
10 [CLSCompliant(false)]
11 public class WixVersionLabel
12 {
13 /// <summary>
14 /// Creates a string only version label.
15 /// </summary>
16 /// <param name="label">String value for version label.</param>
17 public WixVersionLabel(string label)
18 {
19 this.Label = label;
20 }
21
22 /// <summary>
23 /// Creates a string version label with numeric value.
24 /// </summary>
25 /// <param name="label">String value for version label.</param>
26 /// <param name="numeric">Numeric value for the version label.</param>
27 public WixVersionLabel(string label, uint? numeric)
28 {
29 this.Label = label;
30 this.Numeric = numeric;
31 }
32
33 /// <summary>
34 /// Gets the string label value.
35 /// </summary>
36 public string Label { get; set; }
37
38 /// <summary>
39 /// Gets the optional numeric label value.
40 /// </summary>
41 public uint? Numeric { get; set; }
42 }
43}
diff --git a/src/ext/NetFx/be/detectnetcore.cpp b/src/ext/NetFx/be/detectnetcore.cpp
index aeb04203..3ed26549 100644
--- a/src/ext/NetFx/be/detectnetcore.cpp
+++ b/src/ext/NetFx/be/detectnetcore.cpp
@@ -12,18 +12,7 @@ HRESULT DetectNetCore(
12{ 12{
13 HRESULT hr = S_OK; 13 HRESULT hr = S_OK;
14 LPCWSTR wzRuntimeType = NULL; 14 LPCWSTR wzRuntimeType = NULL;
15 LPCWSTR wzPlatformName = NULL; 15 LPWSTR sczArguments = NULL;
16 LPWSTR sczExePath = NULL;
17 LPWSTR sczCommandLine = NULL;
18 HANDLE hProcess = NULL;
19 HANDLE hStdOutErr = INVALID_HANDLE_VALUE;
20 BYTE* rgbOutput = NULL;
21 DWORD cbOutput = 0;
22 DWORD cbTotalRead = 0;
23 DWORD cbRead = 0;
24 DWORD dwExitCode = 0;
25
26 ReleaseNullStr(*psczLatestVersion);
27 16
28 switch (runtimeType) 17 switch (runtimeType)
29 { 18 {
@@ -41,80 +30,14 @@ HRESULT DetectNetCore(
41 break; 30 break;
42 } 31 }
43 32
44 switch (platform) 33 hr = StrAllocFormatted(&sczArguments, L"runtime %ls %ls", wzMajorVersion, wzRuntimeType);
45 { 34 BextExitOnFailure(hr, "Failed to build runtime netcoresearch.exe arguments.");
46 case NETFX_NET_CORE_PLATFORM_ARM64:
47 wzPlatformName = L"arm64";
48 break;
49 case NETFX_NET_CORE_PLATFORM_X64:
50 wzPlatformName = L"x64";
51 break;
52 case NETFX_NET_CORE_PLATFORM_X86:
53 wzPlatformName = L"x86";
54 break;
55 default:
56 BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown platform: %u", platform);
57 break;
58 }
59
60 hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName);
61 BextExitOnFailure(hr, "Failed to build netcoresearch.exe path.");
62
63 hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" runtime %ls %ls", sczExePath, wzMajorVersion, wzRuntimeType);
64 BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line.");
65
66 hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr);
67 if (HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH) == hr)
68 {
69 ExitFunction1(hr = S_FALSE);
70 }
71 BextExitOnFailure(hr, "Failed to run: %ls", sczCommandLine);
72
73 cbOutput = 64;
74 35
75 rgbOutput = reinterpret_cast<BYTE*>(MemAlloc(cbOutput, TRUE)); 36 hr = RunNetCoreSearch(platform, wzBaseDirectory, sczArguments, psczLatestVersion);
76 BextExitOnNull(rgbOutput, hr, E_OUTOFMEMORY, "Failed to alloc output string."); 37 BextExitOnFailure(hr, "Failed to run netcoresearch.exe for runtime.");
77
78 while (::ReadFile(hStdOutErr, rgbOutput + cbTotalRead, cbOutput - cbTotalRead, &cbRead, NULL))
79 {
80 cbTotalRead += cbRead;
81
82 if (cbTotalRead == cbOutput)
83 {
84 cbOutput *= 2;
85
86 LPVOID pvNew = MemReAlloc(rgbOutput, cbOutput, TRUE);
87 BextExitOnNull(pvNew, hr, E_OUTOFMEMORY, "Failed to realloc output string.");
88
89 rgbOutput = reinterpret_cast<BYTE*>(pvNew);
90 }
91 }
92
93 if (ERROR_BROKEN_PIPE != ::GetLastError())
94 {
95 BextExitWithLastError(hr, "Failed to read netcoresearch.exe output.");
96 }
97
98 hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode);
99 BextExitOnFailure(hr, "Failed to wait for netcoresearch.exe to exit.");
100
101 if (0 != dwExitCode)
102 {
103 BextExitWithRootFailure(hr, E_UNEXPECTED, "netcoresearch.exe failed with exit code: 0x%x\r\nOutput:\r\n%hs", dwExitCode, rgbOutput);
104 }
105
106 if (*rgbOutput)
107 {
108 hr = StrAllocStringAnsi(psczLatestVersion, reinterpret_cast<LPSTR>(rgbOutput), 0, CP_UTF8);
109 BextExitOnFailure(hr, "Failed to widen output string: %hs", rgbOutput);
110 }
111 38
112LExit: 39LExit:
113 ReleaseFileHandle(hStdOutErr); 40 ReleaseStr(sczArguments);
114 ReleaseHandle(hProcess);
115 ReleaseMem(rgbOutput);
116 ReleaseStr(sczCommandLine);
117 ReleaseStr(sczExePath);
118 41
119 return hr; 42 return hr;
120} 43}
@@ -136,5 +59,7 @@ HRESULT NetfxPerformDetectNetCore(
136 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion); 59 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion);
137 60
138LExit: 61LExit:
62 ReleaseStr(sczLatestVersion);
63
139 return hr; 64 return hr;
140} 65}
diff --git a/src/ext/NetFx/be/detectnetcoresdk.cpp b/src/ext/NetFx/be/detectnetcoresdk.cpp
index 08b18334..332d8712 100644
--- a/src/ext/NetFx/be/detectnetcoresdk.cpp
+++ b/src/ext/NetFx/be/detectnetcoresdk.cpp
@@ -4,99 +4,22 @@
4 4
5HRESULT DetectNetCoreSdk( 5HRESULT DetectNetCoreSdk(
6 __in NETFX_NET_CORE_PLATFORM platform, 6 __in NETFX_NET_CORE_PLATFORM platform,
7 __in LPCWSTR wzVersion, 7 __in LPCWSTR wzMajorVersion,
8 __in LPCWSTR wzBaseDirectory, 8 __in LPCWSTR wzBaseDirectory,
9 __inout LPWSTR* psczLatestVersion 9 __inout LPWSTR* psczLatestVersion
10 ) 10 )
11{ 11{
12 HRESULT hr = S_OK; 12 HRESULT hr = S_OK;
13 LPCWSTR wzPlatformName = NULL; 13 LPWSTR sczArguments = NULL;
14 LPWSTR sczExePath = NULL;
15 LPWSTR sczCommandLine = NULL;
16 HANDLE hProcess = NULL;
17 HANDLE hStdOutErr = INVALID_HANDLE_VALUE;
18 BYTE* rgbOutput = NULL;
19 DWORD cbOutput = 0;
20 DWORD cbTotalRead = 0;
21 DWORD cbRead = 0;
22 DWORD dwExitCode = 0;
23 14
24 ReleaseNullStr(*psczLatestVersion); 15 hr = StrAllocFormatted(&sczArguments, L"sdk %ls", wzMajorVersion);
16 BextExitOnFailure(hr, "Failed to build sdk netcoresearch.exe arguments.");
25 17
26 switch (platform) 18 hr = RunNetCoreSearch(platform, wzBaseDirectory, sczArguments, psczLatestVersion);
27 { 19 BextExitOnFailure(hr, "Failed to run netcoresearch.exe for sdk.");
28 case NETFX_NET_CORE_PLATFORM_ARM64:
29 wzPlatformName = L"arm64";
30 break;
31 case NETFX_NET_CORE_PLATFORM_X64:
32 wzPlatformName = L"x64";
33 break;
34 case NETFX_NET_CORE_PLATFORM_X86:
35 wzPlatformName = L"x86";
36 break;
37 default:
38 BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown platform: %u", platform);
39 break;
40 }
41
42 hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName);
43 BextExitOnFailure(hr, "Failed to build netcoresearch.exe path.");
44
45 hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" sdk %ls", sczExePath, wzVersion);
46 BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line.");
47
48 hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr);
49 if (HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH) == hr)
50 {
51 ExitFunction1(hr = S_FALSE);
52 }
53 BextExitOnFailure(hr, "Failed to run: %ls", sczCommandLine);
54
55 cbOutput = 64;
56
57 rgbOutput = static_cast<BYTE*>(MemAlloc(cbOutput, TRUE));
58 BextExitOnNull(rgbOutput, hr, E_OUTOFMEMORY, "Failed to alloc output string.");
59
60 while (::ReadFile(hStdOutErr, rgbOutput + cbTotalRead, cbOutput - cbTotalRead, &cbRead, NULL))
61 {
62 cbTotalRead += cbRead;
63
64 if (cbTotalRead == cbOutput)
65 {
66 cbOutput *= 2;
67
68 const LPVOID pvNew = MemReAlloc(rgbOutput, cbOutput, TRUE);
69 BextExitOnNull(pvNew, hr, E_OUTOFMEMORY, "Failed to realloc output string.");
70
71 rgbOutput = static_cast<BYTE*>(pvNew);
72 }
73 }
74
75 if (ERROR_BROKEN_PIPE != ::GetLastError())
76 {
77 BextExitWithLastError(hr, "Failed to read netcoresearch.exe output.");
78 }
79
80 hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode);
81 BextExitOnFailure(hr, "Failed to wait for netcoresearch.exe to exit.");
82
83 if (0 != dwExitCode)
84 {
85 BextExitWithRootFailure(hr, E_UNEXPECTED, "netcoresearch.exe failed with exit code: 0x%x\r\nOutput:\r\n%hs", dwExitCode, rgbOutput);
86 }
87
88 if (*rgbOutput)
89 {
90 hr = StrAllocStringAnsi(psczLatestVersion, reinterpret_cast<LPSTR>(rgbOutput), 0, CP_UTF8);
91 BextExitOnFailure(hr, "Failed to widen output string: %hs", rgbOutput);
92 }
93 20
94LExit: 21LExit:
95 ReleaseFileHandle(hStdOutErr); 22 ReleaseStr(sczArguments);
96 ReleaseHandle(hProcess);
97 ReleaseMem(rgbOutput);
98 ReleaseStr(sczCommandLine);
99 ReleaseStr(sczExePath);
100 23
101 return hr; 24 return hr;
102} 25}
@@ -109,14 +32,16 @@ HRESULT NetfxPerformDetectNetCoreSdk(
109 ) 32 )
110{ 33{
111 HRESULT hr = S_OK; 34 HRESULT hr = S_OK;
112 LPWSTR sczLatestVersion = nullptr; 35 LPWSTR sczLatestVersion = NULL;
113 const auto& searchParams = pSearch->NetCoreSdkSearch; 36
114 hr = DetectNetCoreSdk(searchParams.platform, searchParams.sczVersion, wzBaseDirectory, &sczLatestVersion); 37 hr = DetectNetCoreSdk(pSearch->NetCoreSdkSearch.platform, pSearch->NetCoreSdkSearch.sczMajorVersion, wzBaseDirectory, &sczLatestVersion);
115 BextExitOnFailure(hr, "DetectNetCoreSdk failed."); 38 BextExitOnFailure(hr, "DetectNetCoreSdk failed.");
116 39
117 hr = pEngine->SetVariableVersion(wzVariable, sczLatestVersion); 40 hr = pEngine->SetVariableVersion(wzVariable, sczLatestVersion);
118 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion); 41 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion);
119 42
120LExit: 43LExit:
44 ReleaseStr(sczLatestVersion);
45
121 return hr; 46 return hr;
122} 47}
diff --git a/src/ext/NetFx/be/detectnetcoresdkfeatureband.cpp b/src/ext/NetFx/be/detectnetcoresdkfeatureband.cpp
new file mode 100644
index 00000000..d48c7a85
--- /dev/null
+++ b/src/ext/NetFx/be/detectnetcoresdkfeatureband.cpp
@@ -0,0 +1,55 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5HRESULT DetectNetCoreSdkFeatureBand(
6 __in NETFX_NET_CORE_PLATFORM platform,
7 __in LPCWSTR wzMajorVersion,
8 __in LPCWSTR wzMinorVersion,
9 __in LPCWSTR wzPatchVersion,
10 __in LPCWSTR wzBaseDirectory,
11 __inout LPWSTR* psczLatestVersion
12 )
13{
14 HRESULT hr = S_OK;
15 LPWSTR sczArguments = NULL;
16
17 hr = StrAllocFormatted(&sczArguments, L"sdkfeatureband %ls %ls %ls", wzMajorVersion, wzMinorVersion, wzPatchVersion);
18 BextExitOnFailure(hr, "Failed to build sdkfeatureband netcoresearch.exe arguments.");
19
20 hr = RunNetCoreSearch(platform, wzBaseDirectory, sczArguments, psczLatestVersion);
21 BextExitOnFailure(hr, "Failed to run netcoresearch.exe for sdkfeatureband.");
22
23LExit:
24 ReleaseStr(sczArguments);
25
26 return hr;
27}
28
29HRESULT NetfxPerformDetectNetCoreSdkFeatureBand(
30 __in LPCWSTR wzVariable,
31 __in NETFX_SEARCH* pSearch,
32 __in IBundleExtensionEngine* pEngine,
33 __in LPCWSTR wzBaseDirectory
34 )
35{
36 HRESULT hr = S_OK;
37 LPWSTR sczLatestVersion = NULL;
38
39 hr = DetectNetCoreSdkFeatureBand(
40 pSearch->NetCoreSdkFeatureBandSearch.platform,
41 pSearch->NetCoreSdkFeatureBandSearch.sczMajorVersion,
42 pSearch->NetCoreSdkFeatureBandSearch.sczMinorVersion,
43 pSearch->NetCoreSdkFeatureBandSearch.sczPatchVersion,
44 wzBaseDirectory,
45 &sczLatestVersion);
46 BextExitOnFailure(hr, "DetectNetCoreSdkFeatureBand failed.");
47
48 hr = pEngine->SetVariableVersion(wzVariable, sczLatestVersion);
49 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion);
50
51LExit:
52 ReleaseStr(sczLatestVersion);
53
54 return hr;
55}
diff --git a/src/ext/NetFx/be/detectnetcoresdkfeatureband.h b/src/ext/NetFx/be/detectnetcoresdkfeatureband.h
new file mode 100644
index 00000000..1f92cd58
--- /dev/null
+++ b/src/ext/NetFx/be/detectnetcoresdkfeatureband.h
@@ -0,0 +1,9 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4HRESULT NetfxPerformDetectNetCoreSdkFeatureBand(
5 __in LPCWSTR wzVariable,
6 __in NETFX_SEARCH* pSearch,
7 __in IBundleExtensionEngine* pEngine,
8 __in LPCWSTR wzBaseDirectory
9 );
diff --git a/src/ext/NetFx/be/netfxbe.vcxproj b/src/ext/NetFx/be/netfxbe.vcxproj
index 0408da72..94026960 100644
--- a/src/ext/NetFx/be/netfxbe.vcxproj
+++ b/src/ext/NetFx/be/netfxbe.vcxproj
@@ -48,20 +48,24 @@
48 <ItemGroup> 48 <ItemGroup>
49 <ClCompile Include="detectnetcore.cpp" /> 49 <ClCompile Include="detectnetcore.cpp" />
50 <ClCompile Include="detectnetcoresdk.cpp" /> 50 <ClCompile Include="detectnetcoresdk.cpp" />
51 <ClCompile Include="detectnetcoresdkfeatureband.cpp" />
51 <ClCompile Include="netfxbe.cpp" /> 52 <ClCompile Include="netfxbe.cpp" />
52 <ClCompile Include="NetfxBundleExtension.cpp" /> 53 <ClCompile Include="NetfxBundleExtension.cpp" />
53 <ClCompile Include="netfxsearch.cpp" /> 54 <ClCompile Include="netfxsearch.cpp" />
54 <ClCompile Include="precomp.cpp"> 55 <ClCompile Include="precomp.cpp">
55 <PrecompiledHeader>Create</PrecompiledHeader> 56 <PrecompiledHeader>Create</PrecompiledHeader>
56 </ClCompile> 57 </ClCompile>
58 <ClCompile Include="runnetcoresearch.cpp" />
57 </ItemGroup> 59 </ItemGroup>
58 60
59 <ItemGroup> 61 <ItemGroup>
60 <ClInclude Include="detectnetcore.h" /> 62 <ClInclude Include="detectnetcore.h" />
61 <ClInclude Include="detectnetcoresdk.h" /> 63 <ClInclude Include="detectnetcoresdk.h" />
64 <ClInclude Include="detectnetcoresdkfeatureband.h" />
62 <ClInclude Include="NetfxBundleExtension.h" /> 65 <ClInclude Include="NetfxBundleExtension.h" />
63 <ClInclude Include="netfxsearch.h" /> 66 <ClInclude Include="netfxsearch.h" />
64 <ClInclude Include="precomp.h" /> 67 <ClInclude Include="precomp.h" />
68 <ClInclude Include="runnetcoresearch.h" />
65 </ItemGroup> 69 </ItemGroup>
66 70
67 <ItemGroup> 71 <ItemGroup>
diff --git a/src/ext/NetFx/be/netfxsearch.cpp b/src/ext/NetFx/be/netfxsearch.cpp
index 671e7546..ffbf6ee0 100644
--- a/src/ext/NetFx/be/netfxsearch.cpp
+++ b/src/ext/NetFx/be/netfxsearch.cpp
@@ -15,7 +15,7 @@ STDMETHODIMP NetfxSearchParseFromXml(
15 BSTR bstrNodeName = NULL; 15 BSTR bstrNodeName = NULL;
16 16
17 // Select Netfx search nodes. 17 // Select Netfx search nodes.
18 hr = XmlSelectNodes(pixnBundleExtension, L"NetFxNetCoreSearch|NetFxNetCoreSdkSearch", &pixnNodes); 18 hr = XmlSelectNodes(pixnBundleExtension, L"NetFxNetCoreSearch|NetFxNetCoreSdkSearch|NetFxNetCoreSdkFeatureBandSearch", &pixnNodes);
19 BextExitOnFailure(hr, "Failed to select Netfx search nodes."); 19 BextExitOnFailure(hr, "Failed to select Netfx search nodes.");
20 20
21 // Get Netfx search node count. 21 // Get Netfx search node count.
@@ -72,9 +72,30 @@ STDMETHODIMP NetfxSearchParseFromXml(
72 hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast<DWORD*>(&netCoreSdkSearch.platform)); 72 hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast<DWORD*>(&netCoreSdkSearch.platform));
73 BextExitOnFailure(hr, "Failed to get @Platform."); 73 BextExitOnFailure(hr, "Failed to get @Platform.");
74 74
75 // @Version 75 // @MajorVersion
76 hr = XmlGetAttributeEx(pixnNode, L"Version", &netCoreSdkSearch.sczVersion); 76 hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSdkSearch.sczMajorVersion);
77 BextExitOnFailure(hr, "Failed to get @Version."); 77 BextExitOnFailure(hr, "Failed to get @MajorVersion.");
78 }
79 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"NetFxNetCoreSdkFeatureBandSearch", -1))
80 {
81 pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SDK_FEATURE_BAND_SEARCH;
82
83 auto& netCoreSdkSearch = pSearch->NetCoreSdkFeatureBandSearch;
84 // @Platform
85 hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast<DWORD*>(&netCoreSdkSearch.platform));
86 BextExitOnFailure(hr, "Failed to get @Platform.");
87
88 // @MajorVersion
89 hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSdkSearch.sczMajorVersion);
90 BextExitOnFailure(hr, "Failed to get @MajorVersion.");
91
92 // @MinorVersion
93 hr = XmlGetAttributeEx(pixnNode, L"MinorVersion", &netCoreSdkSearch.sczMinorVersion);
94 BextExitOnFailure(hr, "Failed to get @MinorVersion.");
95
96 // @PatchVersion
97 hr = XmlGetAttributeEx(pixnNode, L"PatchVersion", &netCoreSdkSearch.sczPatchVersion);
98 BextExitOnFailure(hr, "Failed to get @PatchVersion.");
78 } 99 }
79 else 100 else
80 { 101 {
@@ -132,6 +153,9 @@ STDMETHODIMP NetfxSearchExecute(
132 case NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH: 153 case NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH:
133 hr = NetfxPerformDetectNetCoreSdk(wzVariable, pSearch, pEngine, wzBaseDirectory); 154 hr = NetfxPerformDetectNetCoreSdk(wzVariable, pSearch, pEngine, wzBaseDirectory);
134 break; 155 break;
156 case NETFX_SEARCH_TYPE_NET_CORE_SDK_FEATURE_BAND_SEARCH:
157 hr = NetfxPerformDetectNetCoreSdkFeatureBand(wzVariable, pSearch, pEngine, wzBaseDirectory);
158 break;
135 default: 159 default:
136 hr = E_UNEXPECTED; 160 hr = E_UNEXPECTED;
137 } 161 }
diff --git a/src/ext/NetFx/be/netfxsearch.h b/src/ext/NetFx/be/netfxsearch.h
index f4e4db01..5793dd55 100644
--- a/src/ext/NetFx/be/netfxsearch.h
+++ b/src/ext/NetFx/be/netfxsearch.h
@@ -9,6 +9,7 @@ enum NETFX_SEARCH_TYPE
9 NETFX_SEARCH_TYPE_NONE, 9 NETFX_SEARCH_TYPE_NONE,
10 NETFX_SEARCH_TYPE_NET_CORE_SEARCH, 10 NETFX_SEARCH_TYPE_NET_CORE_SEARCH,
11 NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH, 11 NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH,
12 NETFX_SEARCH_TYPE_NET_CORE_SDK_FEATURE_BAND_SEARCH,
12}; 13};
13 14
14enum NETFX_NET_CORE_RUNTIME_TYPE 15enum NETFX_NET_CORE_RUNTIME_TYPE
@@ -44,8 +45,15 @@ typedef struct _NETFX_SEARCH
44 struct 45 struct
45 { 46 {
46 NETFX_NET_CORE_PLATFORM platform; 47 NETFX_NET_CORE_PLATFORM platform;
47 LPWSTR sczVersion; 48 LPWSTR sczMajorVersion;
48 } NetCoreSdkSearch; 49 } NetCoreSdkSearch;
50 struct
51 {
52 NETFX_NET_CORE_PLATFORM platform;
53 LPWSTR sczMajorVersion;
54 LPWSTR sczMinorVersion;
55 LPWSTR sczPatchVersion;
56 } NetCoreSdkFeatureBandSearch;
49 }; 57 };
50} NETFX_SEARCH; 58} NETFX_SEARCH;
51 59
diff --git a/src/ext/NetFx/be/precomp.h b/src/ext/NetFx/be/precomp.h
index 4a774200..c164834d 100644
--- a/src/ext/NetFx/be/precomp.h
+++ b/src/ext/NetFx/be/precomp.h
@@ -31,4 +31,6 @@
31#include "netfxsearch.h" 31#include "netfxsearch.h"
32#include "detectnetcore.h" 32#include "detectnetcore.h"
33#include "detectnetcoresdk.h" 33#include "detectnetcoresdk.h"
34#include "detectnetcoresdkfeatureband.h"
34#include "NetfxBundleExtension.h" 35#include "NetfxBundleExtension.h"
36#include "runnetcoresearch.h"
diff --git a/src/ext/NetFx/be/runnetcoresearch.cpp b/src/ext/NetFx/be/runnetcoresearch.cpp
new file mode 100644
index 00000000..8f38e0d2
--- /dev/null
+++ b/src/ext/NetFx/be/runnetcoresearch.cpp
@@ -0,0 +1,102 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5HRESULT RunNetCoreSearch(
6 __in NETFX_NET_CORE_PLATFORM platform,
7 __in LPCWSTR wzBaseDirectory,
8 __in LPCWSTR wzArguments,
9 __inout LPWSTR* psczLatestVersion
10 )
11{
12 HRESULT hr = S_OK;
13 LPCWSTR wzPlatformName = NULL;
14 LPWSTR sczExePath = NULL;
15 LPWSTR sczCommandLine = NULL;
16 HANDLE hProcess = NULL;
17 HANDLE hStdOutErr = INVALID_HANDLE_VALUE;
18 BYTE* rgbOutput = NULL;
19 DWORD cbOutput = 0;
20 DWORD cbTotalRead = 0;
21 DWORD cbRead = 0;
22 DWORD dwExitCode = 0;
23
24 ReleaseNullStr(*psczLatestVersion);
25
26 switch (platform)
27 {
28 case NETFX_NET_CORE_PLATFORM_ARM64:
29 wzPlatformName = L"arm64";
30 break;
31 case NETFX_NET_CORE_PLATFORM_X64:
32 wzPlatformName = L"x64";
33 break;
34 case NETFX_NET_CORE_PLATFORM_X86:
35 wzPlatformName = L"x86";
36 break;
37 default:
38 BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown platform: %u", platform);
39 break;
40 }
41
42 hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName);
43 BextExitOnFailure(hr, "Failed to build netcoresearch.exe path.");
44
45 hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" %ls", sczExePath, wzArguments);
46 BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line.");
47
48 hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr);
49 if (HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH) == hr)
50 {
51 ExitFunction1(hr = S_FALSE);
52 }
53 BextExitOnFailure(hr, "Failed to run: %ls", sczCommandLine);
54
55 cbOutput = 64;
56
57 rgbOutput = reinterpret_cast<BYTE*>(MemAlloc(cbOutput, TRUE));
58 BextExitOnNull(rgbOutput, hr, E_OUTOFMEMORY, "Failed to alloc output string.");
59
60 while (::ReadFile(hStdOutErr, rgbOutput + cbTotalRead, cbOutput - cbTotalRead, &cbRead, NULL))
61 {
62 cbTotalRead += cbRead;
63
64 if (cbTotalRead == cbOutput)
65 {
66 cbOutput *= 2;
67
68 LPVOID pvNew = MemReAlloc(rgbOutput, cbOutput, TRUE);
69 BextExitOnNull(pvNew, hr, E_OUTOFMEMORY, "Failed to realloc output string.");
70
71 rgbOutput = reinterpret_cast<BYTE*>(pvNew);
72 }
73 }
74
75 if (ERROR_BROKEN_PIPE != ::GetLastError())
76 {
77 BextExitWithLastError(hr, "Failed to read netcoresearch.exe output.");
78 }
79
80 hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode);
81 BextExitOnFailure(hr, "Failed to wait for netcoresearch.exe to exit.");
82
83 if (0 != dwExitCode)
84 {
85 BextExitWithRootFailure(hr, E_UNEXPECTED, "netcoresearch.exe failed with exit code: 0x%x\r\nOutput:\r\n%hs", dwExitCode, rgbOutput);
86 }
87
88 if (*rgbOutput)
89 {
90 hr = StrAllocStringAnsi(psczLatestVersion, reinterpret_cast<LPSTR>(rgbOutput), 0, CP_UTF8);
91 BextExitOnFailure(hr, "Failed to widen output string: %hs", rgbOutput);
92 }
93
94LExit:
95 ReleaseFileHandle(hStdOutErr);
96 ReleaseHandle(hProcess);
97 ReleaseMem(rgbOutput);
98 ReleaseStr(sczCommandLine);
99 ReleaseStr(sczExePath);
100
101 return hr;
102}
diff --git a/src/ext/NetFx/be/runnetcoresearch.h b/src/ext/NetFx/be/runnetcoresearch.h
new file mode 100644
index 00000000..78e6b24a
--- /dev/null
+++ b/src/ext/NetFx/be/runnetcoresearch.h
@@ -0,0 +1,9 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4HRESULT RunNetCoreSearch(
5 __in NETFX_NET_CORE_PLATFORM platform,
6 __in LPCWSTR wzBaseDirectory,
7 __in LPCWSTR wzArguments,
8 __inout LPWSTR* psczLatestVersion
9 );
diff --git a/src/ext/NetFx/netcoresearch/netcoresearch.cpp b/src/ext/NetFx/netcoresearch/netcoresearch.cpp
index 5cf6d10b..8c788461 100644
--- a/src/ext/NetFx/netcoresearch/netcoresearch.cpp
+++ b/src/ext/NetFx/netcoresearch/netcoresearch.cpp
@@ -2,137 +2,155 @@
2 2
3#include "precomp.h" 3#include "precomp.h"
4 4
5enum class NETCORESEARCHKIND 5enum class NETCORESEARCHTYPE
6{ 6{
7 None, 7 None,
8 Runtime, 8 Runtime,
9 Sdk, 9 Sdk,
10 SdkFeatureBand,
10}; 11};
11 12
12struct NETCORESEARCH_STATE 13struct NETCORESEARCH_STATE
13{ 14{
14 NETCORESEARCHKIND Kind = NETCORESEARCHKIND::None; 15 NETCORESEARCHTYPE type;
15 union 16 HRESULT hrSearch;
16 {
17 struct
18 {
19 LPCWSTR wzTargetName;
20 DWORD dwMajorVersion;
21 } Runtime;
22 struct
23 {
24 DWORD dwMajorVersion;
25 DWORD dwMinorVersion;
26 DWORD dwFeatureBand;
27 }
28 Sdk;
29 } Data;
30 VERUTIL_VERSION* pVersion; 17 VERUTIL_VERSION* pVersion;
18
19 struct
20 {
21 LPCWSTR wzTargetName;
22 DWORD dwMajorVersion;
23 } Runtime;
24 struct
25 {
26 DWORD dwMajorVersion;
27 } Sdk;
28 struct
29 {
30 DWORD dwMajorVersion;
31 DWORD dwMinorVersion;
32 DWORD dwPatchVersion;
33 } SdkFeatureBand;
31}; 34};
32 35
36static HRESULT GetSearchStateFromArguments(
37 __in int argc,
38 __in LPWSTR argv[],
39 __in NETCORESEARCH_STATE* pSearchState
40 );
33static HRESULT GetDotnetEnvironmentInfo( 41static HRESULT GetDotnetEnvironmentInfo(
34 __in NETCORESEARCH_STATE& pSearchState, 42 __in NETCORESEARCH_STATE* pSearchState
35 __inout VERUTIL_VERSION** ppVersion
36 ); 43 );
37static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult( 44static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult(
38 __in const hostfxr_dotnet_environment_info* pInfo, 45 __in const hostfxr_dotnet_environment_info* pInfo,
39 __in LPVOID pvContext 46 __in LPVOID pvContext
40 ); 47 );
41 48
42bool string_equal_invariant(__in PCWSTR const x,__in PCWSTR const y) { return CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, x, -1, y, -1); }
43
44HRESULT get_search_state_from_arguments(__in int argc, __in LPWSTR argv[], __out NETCORESEARCH_STATE& searchState);
45
46int __cdecl wmain(int argc, LPWSTR argv[]) 49int __cdecl wmain(int argc, LPWSTR argv[])
47{ 50{
48 HRESULT hr = S_OK; 51 HRESULT hr = S_OK;
49 VERUTIL_VERSION* pVersion = NULL; 52 NETCORESEARCH_STATE searchState = { };
50 NETCORESEARCH_STATE searchState = {};
51
52 ::SetConsoleCP(CP_UTF8);
53 53
54 ConsoleInitialize(); 54 ConsoleInitialize();
55 55
56 hr = get_search_state_from_arguments(argc, argv, OUT searchState); 56 hr = GetSearchStateFromArguments(argc, argv, &searchState);
57 if (FAILED(hr)) 57 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse arguments.");
58 {
59 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse arguments.");
60 }
61 58
62 hr = GetDotnetEnvironmentInfo(searchState, &pVersion); 59 hr = GetDotnetEnvironmentInfo(&searchState);
60 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to search.");
63 61
64 62 if (searchState.pVersion)
65 if (pVersion)
66 { 63 {
67 ConsoleWriteW(CONSOLE_COLOR_NORMAL, pVersion->sczVersion); 64 ConsoleWriteW(CONSOLE_COLOR_NORMAL, searchState.pVersion->sczVersion);
68 } 65 }
69 66
70LExit: 67LExit:
71 ReleaseVerutilVersion(pVersion); 68 ReleaseVerutilVersion(searchState.pVersion);
72 ConsoleUninitialize(); 69 ConsoleUninitialize();
73 return hr; 70 return hr;
74} 71}
75 72
76HRESULT get_search_state_from_arguments(int argc, LPWSTR argv[], __out NETCORESEARCH_STATE& searchState) 73HRESULT GetSearchStateFromArguments(
74 __in int argc,
75 __in LPWSTR argv[],
76 __in NETCORESEARCH_STATE* pSearchState
77 )
77{ 78{
78 HRESULT hr = S_OK; 79 HRESULT hr = S_OK;
79 searchState = {}; 80 LPCWSTR wzSearchKind = NULL;
80 const auto searchKind = argv[1];
81 81
82 if (argc < 3) 82 if (argc < 2)
83 { 83 {
84 ExitFunction1(hr = E_INVALIDARG); 84 ExitFunction1(hr = E_INVALIDARG);
85 } 85 }
86 86
87 wzSearchKind = argv[1];
87 88
88 if (string_equal_invariant(searchKind, L"runtime")) 89 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzSearchKind, -1, L"runtime", -1))
89 { 90 {
90 if (argc != 4) 91 if (argc != 4)
91 { 92 {
92 ExitFunction1(hr = E_INVALIDARG); 93 ExitFunction1(hr = E_INVALIDARG);
93 } 94 }
94 searchState.Kind = NETCORESEARCHKIND::Runtime;
95 95
96 const PCWSTR majorVersion = argv[2]; 96 LPCWSTR wzMajorVersion = argv[2];
97 const PCWSTR targetName = argv[3]; 97 LPCWSTR wzTargetName = argv[3];
98 98
99 auto& data = searchState.Data.Runtime; 99 pSearchState->type = NETCORESEARCHTYPE::Runtime;
100 100
101 data.wzTargetName = targetName; 101 hr = StrStringToUInt32(wzMajorVersion, 0, reinterpret_cast<UINT*>(&pSearchState->Runtime.dwMajorVersion));
102 hr = StrStringToUInt32(majorVersion, 0, reinterpret_cast<UINT*>(&data.dwMajorVersion)); 102 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get target version from: %ls", wzMajorVersion);
103 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get target version from: %ls", majorVersion); 103
104 pSearchState->Runtime.wzTargetName = wzTargetName;
104 } 105 }
105 else if(string_equal_invariant(searchKind, L"sdk")) 106 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzSearchKind, -1, L"sdk", -1))
106 { 107 {
107 searchState.Kind = NETCORESEARCHKIND::Sdk; 108 if (argc != 3)
109 {
110 ExitFunction1(hr = E_INVALIDARG);
111 }
112
113 LPCWSTR wzMajorVersion = argv[2];
108 114
109 const PCWSTR version = argv[2]; 115 pSearchState->type = NETCORESEARCHTYPE::Sdk;
110 116
111 VERUTIL_VERSION* sdkVersion = nullptr; 117 hr = StrStringToUInt32(wzMajorVersion, 0, reinterpret_cast<UINT*>(&pSearchState->Sdk.dwMajorVersion));
112 hr = VerParseVersion(version, 0, FALSE, &sdkVersion); 118 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get sdk major version from: %ls", wzMajorVersion);
113 if (FAILED(hr)) 119 }
120 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzSearchKind, -1, L"sdkfeatureband", -1))
121 {
122 if (argc != 5)
114 { 123 {
115 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse version from: %ls", version); 124 ExitFunction1(hr = E_INVALIDARG);
116 } 125 }
117 126
118 auto& data = searchState.Data.Sdk; 127 LPCWSTR wzMajorVersion = argv[2];
128 LPCWSTR wzMinorVersion = argv[3];
129 LPCWSTR wzPatchVersion = argv[4];
130
131 pSearchState->type = NETCORESEARCHTYPE::SdkFeatureBand;
119 132
120 data.dwMajorVersion = sdkVersion->dwMajor; 133 hr = StrStringToUInt32(wzMajorVersion, 0, reinterpret_cast<UINT*>(&pSearchState->SdkFeatureBand.dwMajorVersion));
121 data.dwMinorVersion = sdkVersion->dwMinor; 134 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get major version from: %ls", wzMajorVersion);
122 data.dwFeatureBand = sdkVersion->dwPatch;
123 135
124 VerFreeVersion(sdkVersion); 136 hr = StrStringToUInt32(wzMinorVersion, 0, reinterpret_cast<UINT*>(&pSearchState->SdkFeatureBand.dwMinorVersion));
137 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get minor version from: %ls", wzMinorVersion);
138
139 hr = StrStringToUInt32(wzPatchVersion, 0, reinterpret_cast<UINT*>(&pSearchState->SdkFeatureBand.dwPatchVersion));
140 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get patch version from: %ls", wzPatchVersion);
141 }
142 else
143 {
144 pSearchState->type = NETCORESEARCHTYPE::None;
145 ExitFunction1(hr = E_INVALIDARG);
125 } 146 }
126 147
127LExit: 148LExit:
128 return hr; 149 return hr;
129} 150}
130 151
131
132
133static HRESULT GetDotnetEnvironmentInfo( 152static HRESULT GetDotnetEnvironmentInfo(
134 __in NETCORESEARCH_STATE& state, 153 __in NETCORESEARCH_STATE* pState
135 __inout VERUTIL_VERSION** ppVersion
136 ) 154 )
137{ 155{
138 HRESULT hr = S_OK; 156 HRESULT hr = S_OK;
@@ -156,17 +174,13 @@ static HRESULT GetDotnetEnvironmentInfo(
156 pfnGetDotnetEnvironmentInfo = (hostfxr_get_dotnet_environment_info_fn)::GetProcAddress(hModule, "hostfxr_get_dotnet_environment_info"); 174 pfnGetDotnetEnvironmentInfo = (hostfxr_get_dotnet_environment_info_fn)::GetProcAddress(hModule, "hostfxr_get_dotnet_environment_info");
157 ConsoleExitOnNullWithLastError(pfnGetDotnetEnvironmentInfo, hr, CONSOLE_COLOR_RED, "Failed to get address for hostfxr_get_dotnet_environment_info."); 175 ConsoleExitOnNullWithLastError(pfnGetDotnetEnvironmentInfo, hr, CONSOLE_COLOR_RED, "Failed to get address for hostfxr_get_dotnet_environment_info.");
158 176
159 hr = pfnGetDotnetEnvironmentInfo(NULL, NULL, GetDotnetEnvironmentInfoResult, &state); 177 hr = pfnGetDotnetEnvironmentInfo(NULL, NULL, GetDotnetEnvironmentInfoResult, pState);
160 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get .NET Core environment info."); 178 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get .NET Core environment info.");
161 179
162 if (state.pVersion) 180 hr = pState->hrSearch;
163 { 181 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to process .NET Core environment info.");
164 *ppVersion = state.pVersion;
165 state.pVersion = NULL;
166 }
167 182
168LExit: 183LExit:
169 ReleaseVerutilVersion(state.pVersion);
170 ReleaseStr(sczHostfxrPath); 184 ReleaseStr(sczHostfxrPath);
171 ReleaseStr(sczProcessPath); 185 ReleaseStr(sczProcessPath);
172 186
@@ -178,108 +192,145 @@ LExit:
178 return hr; 192 return hr;
179} 193}
180 194
181bool matches_feature_band(const int requested, const int actual) 195static HRESULT PerformRuntimeSearch(
196 __in const hostfxr_dotnet_environment_info* pInfo,
197 __in DWORD dwMajorVersion,
198 __in LPCWSTR wzTargetName,
199 __inout VERUTIL_VERSION** ppVersion
200 )
182{ 201{
183 // we have not requested a match on feature band, so skip the check 202 HRESULT hr = S_OK;
184 if (requested == 0) return true; 203 VERUTIL_VERSION* pFrameworkVersion = NULL;
204 int nCompare = 0;
205
206 for (size_t i = 0; i < pInfo->framework_count; ++i)
207 {
208 const hostfxr_dotnet_environment_framework_info* pFrameworkInfo = pInfo->frameworks + i;
209 ReleaseVerutilVersion(pFrameworkVersion);
210
211 if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzTargetName, -1, pFrameworkInfo->name, -1))
212 {
213 continue;
214 }
215
216 hr = VerParseVersion(pFrameworkInfo->version, 0, FALSE, &pFrameworkVersion);
217 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse framework version: %ls", pFrameworkInfo->version);
218
219 if (pFrameworkVersion->dwMajor != dwMajorVersion)
220 {
221 continue;
222 }
223
224 if (*ppVersion)
225 {
226 hr = VerCompareParsedVersions(*ppVersion, pFrameworkVersion, &nCompare);
227 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions.");
185 228
186 const int requestedBand = requested / 100; 229 if (nCompare > -1)
187 const int actualBand = actual / 100; 230 {
231 continue;
232 }
233 }
188 234
189 if (actualBand != requestedBand) return false; 235 ReleaseVerutilVersion(*ppVersion);
236 *ppVersion = pFrameworkVersion;
237 pFrameworkVersion = NULL;
238 }
190 239
191 return actual >= requested; 240LExit:
241 ReleaseVerutilVersion(pFrameworkVersion);
242
243 return hr;
192} 244}
193 245
194static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult( 246static HRESULT PerformSdkSearch(
195 __in const hostfxr_dotnet_environment_info* pInfo, 247 __in const hostfxr_dotnet_environment_info* pInfo,
196 __in LPVOID pvContext 248 __in BOOL fFeatureBand,
249 __in DWORD dwMajorVersion,
250 __in DWORD dwMinorVersion,
251 __in DWORD dwPatchVersion,
252 __inout VERUTIL_VERSION** ppVersion
197 ) 253 )
198{ 254{
199 NETCORESEARCH_STATE* pState = static_cast<NETCORESEARCH_STATE*>(pvContext);
200 HRESULT hr = S_OK; 255 HRESULT hr = S_OK;
201 VERUTIL_VERSION* pDotnetVersion = nullptr; 256 VERUTIL_VERSION* pSdkVersion = NULL;
202 int nCompare = 0; 257 int nCompare = 0;
258 DWORD dwRequestedBand = dwPatchVersion / 100;
203 259
204 260 for (size_t i = 0; i < pInfo->sdk_count; ++i)
205 if (pState->Kind == NETCORESEARCHKIND::Sdk)
206 { 261 {
207 auto& sdkData = pState->Data.Sdk; 262 const hostfxr_dotnet_environment_sdk_info* pSdkInfo = pInfo->sdks + i;
208 for (size_t i = 0; i < pInfo->sdk_count; ++i) 263 ReleaseVerutilVersion(pSdkVersion);
209 {
210 const hostfxr_dotnet_environment_sdk_info* pSdkInfo = pInfo->sdks + i;
211 ReleaseVerutilVersion(pDotnetVersion);
212 264
213 hr = VerParseVersion(pSdkInfo->version, 0, FALSE, &pDotnetVersion); 265 hr = VerParseVersion(pSdkInfo->version, 0, FALSE, &pSdkVersion);
214 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse sdk version: %ls", pSdkInfo->version); 266 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse sdk version: %ls", pSdkInfo->version);
215 267
216 if (pDotnetVersion->dwMajor != sdkData.dwMajorVersion) 268 if (pSdkVersion->dwMajor != dwMajorVersion)
217 { 269 {
218 continue; 270 continue;
219 } 271 }
220 if (!matches_feature_band(sdkData.dwFeatureBand, pDotnetVersion->dwPatch)) 272
273 if (fFeatureBand)
274 {
275 if (pSdkVersion->dwMinor != dwMinorVersion)
221 { 276 {
222 continue; 277 continue;
223 } 278 }
224 279
225 if (pState->pVersion) 280 if ((pSdkVersion->dwPatch / 100) != dwRequestedBand)
226 { 281 {
227 hr = VerCompareParsedVersions(pState->pVersion, pDotnetVersion, &nCompare); 282 continue;
228 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions.");
229
230 if (nCompare > -1)
231 {
232 continue;
233 }
234 } 283 }
235
236 ReleaseVerutilVersion(pState->pVersion);
237 pState->pVersion = pDotnetVersion;
238 pDotnetVersion = nullptr;
239 } 284 }
240 } 285
241 else if(pState->Kind == NETCORESEARCHKIND::Runtime) 286 if (*ppVersion)
242 {
243 auto& runtimeData = pState->Data.Runtime;
244 for (size_t i = 0; i < pInfo->framework_count; ++i)
245 { 287 {
246 const hostfxr_dotnet_environment_framework_info* pFrameworkInfo = pInfo->frameworks + i; 288 hr = VerCompareParsedVersions(*ppVersion, pSdkVersion, &nCompare);
247 ReleaseVerutilVersion(pDotnetVersion); 289 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions.");
248 290
249 if (string_equal_invariant(runtimeData.wzTargetName, pFrameworkInfo->name)) 291 if (nCompare > -1)
250 { 292 {
251 continue; 293 continue;
252 } 294 }
295 }
253 296
254 hr = VerParseVersion(pFrameworkInfo->version, 0, FALSE, &pDotnetVersion); 297 ReleaseVerutilVersion(*ppVersion);
255 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse framework version: %ls", pFrameworkInfo->version); 298 *ppVersion = pSdkVersion;
299 pSdkVersion = NULL;
300 }
256 301
257 if (pDotnetVersion->dwMajor != runtimeData.dwMajorVersion) 302LExit:
258 { 303 ReleaseVerutilVersion(pSdkVersion);
259 continue;
260 }
261 304
262 if (pState->pVersion) 305 return hr;
263 { 306}
264 hr = VerCompareParsedVersions(pState->pVersion, pDotnetVersion, &nCompare);
265 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions.");
266 307
267 if (nCompare > -1) 308static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult(
268 { 309 __in const hostfxr_dotnet_environment_info* pInfo,
269 continue; 310 __in LPVOID pvContext
270 } 311 )
271 } 312{
313 NETCORESEARCH_STATE* pState = static_cast<NETCORESEARCH_STATE*>(pvContext);
314 HRESULT hr = S_OK;
272 315
273 ReleaseVerutilVersion(pState->pVersion); 316 if (pState->type == NETCORESEARCHTYPE::Sdk)
274 pState->pVersion = pDotnetVersion; 317 {
275 pDotnetVersion = nullptr; 318 hr = PerformSdkSearch(pInfo, FALSE, pState->Sdk.dwMajorVersion, 0, 0, &pState->pVersion);
276 } 319 }
320 else if (pState->type == NETCORESEARCHTYPE::SdkFeatureBand)
321 {
322 hr = PerformSdkSearch(pInfo, TRUE, pState->SdkFeatureBand.dwMajorVersion, pState->SdkFeatureBand.dwMinorVersion, pState->SdkFeatureBand.dwPatchVersion, &pState->pVersion);
323 }
324 else if (pState->type == NETCORESEARCHTYPE::Runtime)
325 {
326 hr = PerformRuntimeSearch(pInfo, pState->Runtime.dwMajorVersion, pState->Runtime.wzTargetName, &pState->pVersion);
277 } 327 }
278 else 328 else
279 { 329 {
280 ConsoleWriteError(E_INVALIDARG, CONSOLE_COLOR_RED, "Invalid NETCORESEARCHKIND."); 330 hr = E_INVALIDARG;
331 ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Invalid NETCORESEARCHTYPE.");
281 } 332 }
282 333
283LExit: 334LExit:
284 ReleaseVerutilVersion(pDotnetVersion); 335 pState->hrSearch = hr;
285} 336}
diff --git a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest.wxs b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest.wxs
index b7b55747..812f623b 100644
--- a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest.wxs
+++ b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest.wxs
@@ -7,9 +7,11 @@
7 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x86" /> 7 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x86" />
8 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x86" /> 8 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x86" />
9 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x86" /> 9 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x86" />
10 <PackageGroupRef Id="DotNetCoreSdk31425Redist_x86" />
10 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x64" /> 11 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x64" />
11 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x64" /> 12 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x64" />
12 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x64" /> 13 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x64" />
14 <PackageGroupRef Id="DotNetCoreSdk31425Redist_x64" />
13 </Chain> 15 </Chain>
14 </Bundle> 16 </Bundle>
15</Wix> 17</Wix>
diff --git a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest_x64.wxs b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest_x64.wxs
index 3588686a..a4639d7c 100644
--- a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest_x64.wxs
+++ b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/BundleLatest_x64.wxs
@@ -7,6 +7,7 @@
7 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x64" /> 7 <PackageGroupRef Id="AspNetCoreRuntime3112Redist_x64" />
8 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x64" /> 8 <PackageGroupRef Id="DesktopNetCoreRuntime3112Redist_x64" />
9 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x64" /> 9 <PackageGroupRef Id="DotNetCoreRuntime3112Redist_x64" />
10 <PackageGroupRef Id="DotNetCoreSdk31425Redist_x64" />
10 </Chain> 11 </Chain>
11 </Bundle> 12 </Bundle>
12</Wix> 13</Wix>
diff --git a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x64.wxs b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x64.wxs
index 74e82405..78444901 100644
--- a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x64.wxs
+++ b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x64.wxs
@@ -5,7 +5,7 @@
5 <?define NetCorePlatform = x64?> 5 <?define NetCorePlatform = x64?>
6 <?define NetCoreIdVersion = 3112?> 6 <?define NetCoreIdVersion = 3112?>
7 <?define NetCoreVersion = 3.1.12?> 7 <?define NetCoreVersion = 3.1.12?>
8 <?define NetCoreSdkPlatform = x64?> 8 <?define NetCoreSdkFeatureBandVersion = 31400?>
9 <?define NetCoreSdkIdVersion = 31425?> 9 <?define NetCoreSdkIdVersion = 31425?>
10 <?define NetCoreSdkVersion = 3.1.425?> 10 <?define NetCoreSdkVersion = 3.1.425?>
11 <?include NetCore3_Platform.wxi?> 11 <?include NetCore3_Platform.wxi?>
@@ -61,16 +61,17 @@
61 </Fragment> 61 </Fragment>
62 62
63 <Fragment> 63 <Fragment>
64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCoreSdkPlatform)" Version="3.0.100" Variable="$(var.DotNetCoreSdkId)" /> 64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCorePlatform)" MajorVersion="3" Variable="$(var.DotNetCoreSdkId)" />
65 <netfx:DotNetCoreSdkFeatureBandSearch Id="$(var.DotNetCoreSdkFeatureBandId)" Platform="$(var.NetCorePlatform)" Version="3.1.400" Variable="$(var.DotNetCoreSdkFeatureBandId)" />
65 66
66 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition" Value="$(var.DotNetCoreSdkId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" /> 67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition" Value="$(var.DotNetCoreSdkFeatureBandId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" />
67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition" Value="" Overridable="yes" /> 68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition" Value="" Overridable="yes" />
68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory" Value="redist\" Overridable="yes" /> 69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory" Value="redist\" Overridable="yes" />
69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)RepairArguments" Value="" Overridable="yes" /> 70 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
70 71
71 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)"> 72 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)">
72 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove"> 73 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove">
73 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCoreSdkPlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET Core Runtime - 3.1.425 (x64)" Description="Microsoft .NET Core Runtime - 3.1.425 (x64)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="135024384" Version="3.1.425" /> 74 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET Core Runtime - 3.1.425 (x64)" Description="Microsoft .NET Core Runtime - 3.1.425 (x64)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="135024384" Version="3.1.425" />
74 </ExePackage> 75 </ExePackage>
75 </PackageGroup> 76 </PackageGroup>
76 </Fragment> 77 </Fragment>
diff --git a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x86.wxs b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x86.wxs
index 9acc4dc5..69700d80 100644
--- a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x86.wxs
+++ b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3.1.12_x86.wxs
@@ -5,7 +5,7 @@
5 <?define NetCorePlatform = x86?> 5 <?define NetCorePlatform = x86?>
6 <?define NetCoreIdVersion = 3112?> 6 <?define NetCoreIdVersion = 3112?>
7 <?define NetCoreVersion = 3.1.12?> 7 <?define NetCoreVersion = 3.1.12?>
8 <?define NetCoreSdkPlatform = x86?> 8 <?define NetCoreSdkFeatureBandVersion = 31400?>
9 <?define NetCoreSdkIdVersion = 31425?> 9 <?define NetCoreSdkIdVersion = 31425?>
10 <?define NetCoreSdkVersion = 3.1.425?> 10 <?define NetCoreSdkVersion = 3.1.425?>
11 <?include NetCore3_Platform.wxi?> 11 <?include NetCore3_Platform.wxi?>
@@ -61,16 +61,17 @@
61 </Fragment> 61 </Fragment>
62 62
63 <Fragment> 63 <Fragment>
64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCoreSdkPlatform)" Version="3.0.100" Variable="$(var.DotNetCoreSdkId)" /> 64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCorePlatform)" MajorVersion="3" Variable="$(var.DotNetCoreSdkId)" />
65 <netfx:DotNetCoreSdkFeatureBandSearch Id="$(var.DotNetCoreSdkFeatureBandId)" Platform="$(var.NetCorePlatform)" Version="3.1.400" Variable="$(var.DotNetCoreSdkFeatureBandId)" />
65 66
66 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition" Value="$(var.DotNetCoreSdkId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" /> 67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition" Value="$(var.DotNetCoreSdkFeatureBandId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" />
67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition" Value="" Overridable="yes" /> 68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition" Value="" Overridable="yes" />
68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory" Value="redist\" Overridable="yes" /> 69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory" Value="redist\" Overridable="yes" />
69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)RepairArguments" Value="" Overridable="yes" /> 70 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
70 71
71 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)"> 72 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)">
72 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove"> 73 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove">
73 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCoreSdkPlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET Core SDK - 3.1.425 (x86)" Description="Microsoft .NET Core Runtime - 3.1.12 (x86)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="124974936" Version="3.1.425" /> 74 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET Core SDK - 3.1.425 (x86)" Description="Microsoft .NET Core Runtime - 3.1.12 (x86)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="124974936" Version="3.1.425" />
74 </ExePackage> 75 </ExePackage>
75 </PackageGroup> 76 </PackageGroup>
76 </Fragment> 77 </Fragment>
diff --git a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3_Platform.wxi b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3_Platform.wxi
index 2933196d..affe0143 100644
--- a/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3_Platform.wxi
+++ b/src/ext/NetFx/test/WixToolsetTest.Netfx/TestData/UsingDotNetCorePackages/NetCore3_Platform.wxi
@@ -21,8 +21,9 @@
21 <?define DotNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreRedistLog)]"?> 21 <?define DotNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
22 <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreRedistLog)]"?> 22 <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
23 23
24 <?define DotNetCoreSdkId = DOTNETCORESDK3_$(var.NetCoreSdkPlatform)?> 24 <?define DotNetCoreSdkId = DOTNETCORESDK3_$(var.NetCorePlatform)?>
25 <?define DotNetCoreSdkRedistId = DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist_$(var.NetCoreSdkPlatform)?> 25 <?define DotNetCoreSdkFeatureBandId = DOTNETCORESDK$(var.NetCoreSdkFeatureBandVersion)_$(var.NetCorePlatform)?>
26 <?define DotNetCoreSdkRedistId = DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist_$(var.NetCorePlatform)?>
26 <?define DotNetCoreSdkRedistLog = DotNetCoreSdk$(var.NetCoreSdkIdVersion)RedistLog?> 27 <?define DotNetCoreSdkRedistLog = DotNetCoreSdk$(var.NetCoreSdkIdVersion)RedistLog?>
27 <?define DotNetCoreSdkRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?> 28 <?define DotNetCoreSdkRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?>
28 <?define DotNetCoreSdkRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?> 29 <?define DotNetCoreSdkRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?>
diff --git a/src/ext/NetFx/wixext/NetFxCompiler.cs b/src/ext/NetFx/wixext/NetFxCompiler.cs
index 7a37cf90..c40bc77b 100644
--- a/src/ext/NetFx/wixext/NetFxCompiler.cs
+++ b/src/ext/NetFx/wixext/NetFxCompiler.cs
@@ -55,6 +55,12 @@ namespace WixToolset.Netfx
55 case "DotNetCoreSdkSearchRef": 55 case "DotNetCoreSdkSearchRef":
56 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element); 56 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element);
57 break; 57 break;
58 case "DotNetCoreSdkFeatureBandSearch":
59 this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element);
60 break;
61 case "DotNetCoreSdkFeatureBandSearchRef":
62 this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element);
63 break;
58 case "DotNetCompatibilityCheck": 64 case "DotNetCompatibilityCheck":
59 this.ParseDotNetCompatibilityCheckElement(intermediate, section, element); 65 this.ParseDotNetCompatibilityCheckElement(intermediate, section, element);
60 break; 66 break;
@@ -81,6 +87,12 @@ namespace WixToolset.Netfx
81 case "DotNetCoreSdkSearchRef": 87 case "DotNetCoreSdkSearchRef":
82 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element); 88 this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element);
83 break; 89 break;
90 case "DotNetCoreSdkFeatureBandSearch":
91 this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element);
92 break;
93 case "DotNetCoreSdkFeatureBandSearchRef":
94 this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element);
95 break;
84 default: 96 default:
85 this.ParseHelper.UnexpectedElement(parentElement, element); 97 this.ParseHelper.UnexpectedElement(parentElement, element);
86 break; 98 break;
@@ -267,8 +279,8 @@ namespace WixToolset.Netfx
267 string variable = null; 279 string variable = null;
268 string condition = null; 280 string condition = null;
269 string after = null; 281 string after = null;
270 NetCoreSdkSearchPlatform? platform = null; 282 NetCoreSearchPlatform? platform = null;
271 string version = null; 283 var majorVersion = CompilerConstants.IntegerNotSet;
272 284
273 foreach (var attrib in element.Attributes()) 285 foreach (var attrib in element.Attributes())
274 { 286 {
@@ -293,22 +305,22 @@ namespace WixToolset.Netfx
293 switch (platformValue) 305 switch (platformValue)
294 { 306 {
295 case "arm64": 307 case "arm64":
296 platform = NetCoreSdkSearchPlatform.Arm64; 308 platform = NetCoreSearchPlatform.Arm64;
297 break; 309 break;
298 case "x64": 310 case "x64":
299 platform = NetCoreSdkSearchPlatform.X64; 311 platform = NetCoreSearchPlatform.X64;
300 break; 312 break;
301 case "x86": 313 case "x86":
302 platform = NetCoreSdkSearchPlatform.X86; 314 platform = NetCoreSearchPlatform.X86;
303 break; 315 break;
304 default: 316 default:
305 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86")); 317 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86"));
306 break; 318 break;
307 } 319 }
308 break; 320 break;
309 case "Version": 321 case "MajorVersion":
310 // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic. 322 // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic.
311 version = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib); 323 majorVersion = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 3, Int32.MaxValue);
312 break; 324 break;
313 default: 325 default:
314 this.ParseHelper.UnexpectedAttribute(element, attrib); 326 this.ParseHelper.UnexpectedAttribute(element, attrib);
@@ -331,16 +343,13 @@ namespace WixToolset.Netfx
331 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform")); 343 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
332 } 344 }
333 345
334 346 if (majorVersion == CompilerConstants.IntegerNotSet)
335 if (String.IsNullOrEmpty(version))
336 { 347 {
337 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version")); 348 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "MajorVersion"));
338 } 349 }
339 350 else if (majorVersion == 4)
340 var ver = Version.Parse(version);
341 if (ver.Major == 4)
342 { 351 {
343 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "3.*", "5+.*")); 352 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "MajorVersion", "4", "3", "5+"));
344 } 353 }
345 354
346 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 355 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
@@ -358,7 +367,7 @@ namespace WixToolset.Netfx
358 section.AddSymbol(new NetFxNetCoreSdkSearchSymbol(sourceLineNumbers, id) 367 section.AddSymbol(new NetFxNetCoreSdkSearchSymbol(sourceLineNumbers, id)
359 { 368 {
360 Platform = platform.Value, 369 Platform = platform.Value,
361 Version = version, 370 MajorVersion = majorVersion,
362 }); 371 });
363 } 372 }
364 } 373 }
@@ -391,6 +400,157 @@ namespace WixToolset.Netfx
391 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 400 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
392 } 401 }
393 402
403 private void ParseDotNetCoreSdkFeatureBandSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
404 {
405 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
406 Identifier id = null;
407 string variable = null;
408 string condition = null;
409 string after = null;
410 NetCoreSearchPlatform? platform = null;
411 string version = null;
412 var majorVersion = 0;
413 var minorVersion = 0;
414 var patchVersion = 0;
415
416 foreach (var attrib in element.Attributes())
417 {
418 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
419 {
420 switch (attrib.Name.LocalName)
421 {
422 case "Id":
423 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
424 break;
425 case "Variable":
426 variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
427 break;
428 case "Condition":
429 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
430 break;
431 case "After":
432 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
433 break;
434 case "Platform":
435 var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
436 switch (platformValue)
437 {
438 case "arm64":
439 platform = NetCoreSearchPlatform.Arm64;
440 break;
441 case "x64":
442 platform = NetCoreSearchPlatform.X64;
443 break;
444 case "x86":
445 platform = NetCoreSearchPlatform.X86;
446 break;
447 default:
448 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86"));
449 break;
450 }
451 break;
452 case "Version":
453 version = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
454 break;
455 default:
456 this.ParseHelper.UnexpectedAttribute(element, attrib);
457 break;
458 }
459 }
460 else
461 {
462 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
463 }
464 }
465
466 if (id == null)
467 {
468 id = this.ParseHelper.CreateIdentifier("dncsfbs", variable, condition, after);
469 }
470
471 if (!platform.HasValue)
472 {
473 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform"));
474 }
475
476 if (String.IsNullOrEmpty(version))
477 {
478 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version"));
479 }
480 else
481 {
482 if (!Version.TryParse(version, out var featureBandVersion))
483 {
484 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00"));
485 }
486 else
487 {
488 majorVersion = featureBandVersion.Major;
489 minorVersion = featureBandVersion.Minor;
490 patchVersion = featureBandVersion.Build;
491
492 if ((patchVersion % 100) != 0 || featureBandVersion.Revision != -1)
493 {
494 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00"));
495 }
496
497 if (majorVersion == 4)
498 {
499 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "3.*", "5+.*"));
500 }
501 }
502 }
503
504 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
505
506 var bundleExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBundleExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
507 if (bundleExtensionId == null)
508 {
509 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName));
510 }
511
512 if (!this.Messaging.EncounteredError)
513 {
514 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bundleExtensionId);
515
516 section.AddSymbol(new NetFxNetCoreSdkFeatureBandSearchSymbol(sourceLineNumbers, id)
517 {
518 Platform = platform.Value,
519 MajorVersion = majorVersion,
520 MinorVersion = minorVersion,
521 PatchVersion = patchVersion,
522 });
523 }
524 }
525
526 private void ParseDotNetCoreSdkFeatureBandSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
527 {
528 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
529
530 foreach (var attrib in element.Attributes())
531 {
532 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
533 {
534 switch (attrib.Name.LocalName)
535 {
536 case "Id":
537 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
538 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch, refId);
539 break;
540 default:
541 this.ParseHelper.UnexpectedAttribute(element, attrib);
542 break;
543 }
544 }
545 else
546 {
547 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
548 }
549 }
550
551 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
552 }
553
394 /// <summary> 554 /// <summary>
395 /// Parses a NativeImage element. 555 /// Parses a NativeImage element.
396 /// </summary> 556 /// </summary>
diff --git a/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkFeatureBandSymbol.cs b/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkFeatureBandSymbol.cs
new file mode 100644
index 00000000..ad80f9d2
--- /dev/null
+++ b/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkFeatureBandSymbol.cs
@@ -0,0 +1,71 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Netfx
4{
5 using WixToolset.Data;
6 using WixToolset.Netfx.Symbols;
7
8 public static partial class NetfxSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition NetFxNetCoreSdkFeatureBandSearch = new IntermediateSymbolDefinition(
11 NetfxSymbolDefinitionType.NetFxNetCoreSdkFeatureBandSearch.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkFeatureBandSearchSymbolFields.Platform), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkFeatureBandSearchSymbolFields.MajorVersion), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkFeatureBandSearchSymbolFields.MinorVersion), IntermediateFieldType.Number),
17 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkFeatureBandSearchSymbolFields.PatchVersion), IntermediateFieldType.Number),
18 },
19 typeof(NetFxNetCoreSdkFeatureBandSearchSymbol));
20 }
21}
22
23namespace WixToolset.Netfx.Symbols
24{
25 using WixToolset.Data;
26
27 public enum NetFxNetCoreSdkFeatureBandSearchSymbolFields
28 {
29 Platform,
30 MajorVersion,
31 MinorVersion,
32 PatchVersion,
33 }
34
35 public class NetFxNetCoreSdkFeatureBandSearchSymbol : IntermediateSymbol
36 {
37 public NetFxNetCoreSdkFeatureBandSearchSymbol() : base(NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch, null, null)
38 {
39 }
40
41 public NetFxNetCoreSdkFeatureBandSearchSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch, sourceLineNumber, id)
42 {
43 }
44
45 public IntermediateField this[NetFxNetCoreSdkFeatureBandSearchSymbolFields index] => this.Fields[(int)index];
46
47 public NetCoreSearchPlatform Platform
48 {
49 get => (NetCoreSearchPlatform)this.Fields[(int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.Platform].AsNumber();
50 set => this.Set((int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.Platform, (int)value);
51 }
52
53 public int MajorVersion
54 {
55 get => this.Fields[(int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.MajorVersion].AsNumber();
56 set => this.Set((int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.MajorVersion, value);
57 }
58
59 public int MinorVersion
60 {
61 get => this.Fields[(int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.MinorVersion].AsNumber();
62 set => this.Set((int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.MinorVersion, value);
63 }
64
65 public int PatchVersion
66 {
67 get => this.Fields[(int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.PatchVersion].AsNumber();
68 set => this.Set((int)NetFxNetCoreSdkFeatureBandSearchSymbolFields.PatchVersion, value);
69 }
70 }
71}
diff --git a/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkSymbol.cs b/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkSymbol.cs
index 86b750ea..a368068e 100644
--- a/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkSymbol.cs
+++ b/src/ext/NetFx/wixext/Symbols/NetFxNetCoreSearchSdkSymbol.cs
@@ -12,9 +12,9 @@ namespace WixToolset.Netfx
12 new[] 12 new[]
13 { 13 {
14 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkSearchSymbolFields.Platform), IntermediateFieldType.Number), 14 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkSearchSymbolFields.Platform), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkSearchSymbolFields.Version), IntermediateFieldType.String), 15 new IntermediateFieldDefinition(nameof(NetFxNetCoreSdkSearchSymbolFields.MajorVersion), IntermediateFieldType.Number),
16 }, 16 },
17 typeof(NetFxNetCoreSearchSymbol)); 17 typeof(NetFxNetCoreSdkSearchSymbol));
18 } 18 }
19} 19}
20 20
@@ -22,21 +22,12 @@ namespace WixToolset.Netfx.Symbols
22{ 22{
23 using WixToolset.Data; 23 using WixToolset.Data;
24 24
25
26 public enum NetCoreSdkSearchPlatform
27 {
28 X86,
29 X64,
30 Arm64,
31 }
32
33 public enum NetFxNetCoreSdkSearchSymbolFields 25 public enum NetFxNetCoreSdkSearchSymbolFields
34 { 26 {
35 Platform, 27 Platform,
36 Version, 28 MajorVersion,
37 } 29 }
38 30
39
40 public class NetFxNetCoreSdkSearchSymbol : IntermediateSymbol 31 public class NetFxNetCoreSdkSearchSymbol : IntermediateSymbol
41 { 32 {
42 public NetFxNetCoreSdkSearchSymbol() : base(NetfxSymbolDefinitions.NetFxNetCoreSdkSearch, null, null) 33 public NetFxNetCoreSdkSearchSymbol() : base(NetfxSymbolDefinitions.NetFxNetCoreSdkSearch, null, null)
@@ -49,16 +40,16 @@ namespace WixToolset.Netfx.Symbols
49 40
50 public IntermediateField this[NetFxNetCoreSdkSearchSymbolFields index] => this.Fields[(int)index]; 41 public IntermediateField this[NetFxNetCoreSdkSearchSymbolFields index] => this.Fields[(int)index];
51 42
52 public NetCoreSdkSearchPlatform Platform 43 public NetCoreSearchPlatform Platform
53 { 44 {
54 get => (NetCoreSdkSearchPlatform)this.Fields[(int)NetFxNetCoreSdkSearchSymbolFields.Platform].AsNumber(); 45 get => (NetCoreSearchPlatform)this.Fields[(int)NetFxNetCoreSdkSearchSymbolFields.Platform].AsNumber();
55 set => this.Set((int)NetFxNetCoreSdkSearchSymbolFields.Platform, (int)value); 46 set => this.Set((int)NetFxNetCoreSdkSearchSymbolFields.Platform, (int)value);
56 } 47 }
57 48
58 public string Version 49 public int MajorVersion
59 { 50 {
60 get => this.Fields[(int)NetFxNetCoreSdkSearchSymbolFields.Version].AsString(); 51 get => this.Fields[(int)NetFxNetCoreSdkSearchSymbolFields.MajorVersion].AsNumber();
61 set => this.Set((int)NetFxNetCoreSdkSearchSymbolFields.Version, value); 52 set => this.Set((int)NetFxNetCoreSdkSearchSymbolFields.MajorVersion, value);
62 } 53 }
63 } 54 }
64} 55}
diff --git a/src/ext/NetFx/wixext/Symbols/NetfxSymbolDefinitions.cs b/src/ext/NetFx/wixext/Symbols/NetfxSymbolDefinitions.cs
index 00c52f9e..1db4f647 100644
--- a/src/ext/NetFx/wixext/Symbols/NetfxSymbolDefinitions.cs
+++ b/src/ext/NetFx/wixext/Symbols/NetfxSymbolDefinitions.cs
@@ -10,8 +10,9 @@ namespace WixToolset.Netfx
10 { 10 {
11 NetFxNativeImage, 11 NetFxNativeImage,
12 NetFxNetCoreSearch, 12 NetFxNetCoreSearch,
13 NetFxNetCoreSdkSearch,
14 NetFxDotNetCompatibilityCheck, 13 NetFxDotNetCompatibilityCheck,
14 NetFxNetCoreSdkSearch,
15 NetFxNetCoreSdkFeatureBandSearch,
15 } 16 }
16 17
17 public static partial class NetfxSymbolDefinitions 18 public static partial class NetfxSymbolDefinitions
@@ -41,6 +42,9 @@ namespace WixToolset.Netfx
41 case NetfxSymbolDefinitionType.NetFxNetCoreSdkSearch: 42 case NetfxSymbolDefinitionType.NetFxNetCoreSdkSearch:
42 return NetfxSymbolDefinitions.NetFxNetCoreSdkSearch; 43 return NetfxSymbolDefinitions.NetFxNetCoreSdkSearch;
43 44
45 case NetfxSymbolDefinitionType.NetFxNetCoreSdkFeatureBandSearch:
46 return NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch;
47
44 case NetfxSymbolDefinitionType.NetFxDotNetCompatibilityCheck: 48 case NetfxSymbolDefinitionType.NetFxDotNetCompatibilityCheck:
45 return NetfxSymbolDefinitions.NetFxDotNetCompatibilityCheck; 49 return NetfxSymbolDefinitions.NetFxDotNetCompatibilityCheck;
46 50
@@ -53,6 +57,7 @@ namespace WixToolset.Netfx
53 { 57 {
54 NetFxNetCoreSearch.AddTag(BurnConstants.BundleExtensionSearchSymbolDefinitionTag); 58 NetFxNetCoreSearch.AddTag(BurnConstants.BundleExtensionSearchSymbolDefinitionTag);
55 NetFxNetCoreSdkSearch.AddTag(BurnConstants.BundleExtensionSearchSymbolDefinitionTag); 59 NetFxNetCoreSdkSearch.AddTag(BurnConstants.BundleExtensionSearchSymbolDefinitionTag);
60 NetFxNetCoreSdkFeatureBandSearch.AddTag(BurnConstants.BundleExtensionSearchSymbolDefinitionTag);
56 } 61 }
57 } 62 }
58} 63}
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6.0.9_x86.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6.0.9_x86.wxs
index c2232674..5840bf61 100644
--- a/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6.0.9_x86.wxs
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6.0.9_x86.wxs
@@ -5,7 +5,7 @@
5 <?define NetCorePlatform = x86?> 5 <?define NetCorePlatform = x86?>
6 <?define NetCoreIdVersion = 609?> 6 <?define NetCoreIdVersion = 609?>
7 <?define NetCoreVersion = 6.0.9?> 7 <?define NetCoreVersion = 6.0.9?>
8 <?define NetCoreSdkPlatform = x86?> 8 <?define NetCoreSdkFeatureBandVersion = 60400?>
9 <?define NetCoreSdkIdVersion = 60403?> 9 <?define NetCoreSdkIdVersion = 60403?>
10 <?define NetCoreSdkVersion = 6.0.403?> 10 <?define NetCoreSdkVersion = 6.0.403?>
11 <?include NetCore6_Platform.wxi?> 11 <?include NetCore6_Platform.wxi?>
@@ -61,16 +61,21 @@
61 </Fragment> 61 </Fragment>
62 62
63 <Fragment> 63 <Fragment>
64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCoreSdkPlatform)" Version="6.0.200" Variable="$(var.DotNetCoreSdkId)" /> 64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCorePlatform)" MajorVersion="6" Variable="$(var.DotNetCoreSdkId)" />
65 <netfx:DotNetCoreSdkFeatureBandSearch Id="$(var.DotNetCoreSdkFeatureBandId)" Platform="$(var.NetCorePlatform)" Version="6.0.400" Variable="$(var.DotNetCoreSdkFeatureBandId)" />
66 </Fragment>
67
68 <Fragment>
69 <netfx:DotNetCoreSdkFeatureBandSearchRef Id="$(var.DotNetCoreSdkFeatureBandId)" />
65 70
66 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition" Value="$(var.DotNetCoreSdkId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" /> 71 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition" Value="$(var.DotNetCoreSdkFeatureBandId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" />
67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition" Value="" Overridable="yes" /> 72 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition" Value="" Overridable="yes" />
68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory" Value="redist\" Overridable="yes" /> 73 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory" Value="redist\" Overridable="yes" />
69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)RepairArguments" Value="" Overridable="yes" /> 74 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
70 75
71 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)"> 76 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)">
72 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove"> 77 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove">
73 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCoreSdkPlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET 6.0 SDK - 6.0.403 (x86)" Description="Microsoft .NET SDK - 6.0.403 (x86)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="194236520" Version="6.0.403" /> 78 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET 6.0 SDK - 6.0.403 (x86)" Description="Microsoft .NET SDK - 6.0.403 (x86)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="194236520" Version="6.0.403" />
74 </ExePackage> 79 </ExePackage>
75 </PackageGroup> 80 </PackageGroup>
76 </Fragment> 81 </Fragment>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6_Platform.wxi b/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6_Platform.wxi
index 8f084b43..c09c3624 100644
--- a/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6_Platform.wxi
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib/NetCore6_Platform.wxi
@@ -21,9 +21,10 @@
21 <?define DotNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreRedistLog)]"?> 21 <?define DotNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
22 <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreRedistLog)]"?> 22 <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
23 23
24 <?define DotNetCoreSdkId = DOTNETCORERUNTIME6_$(var.NetCoreSdkPlatform)?> 24 <?define DotNetCoreSdkId = DOTNETCORESDK6_$(var.NetCorePlatform)?>
25 <?define DotNetCoreSdkRedistId = DotNetCoreRuntime$(var.NetCoreIdVersion)Redist_$(var.NetCoreSdkPlatform)?> 25 <?define DotNetCoreSdkFeatureBandId = DOTNETCORESDK$(var.NetCoreSdkFeatureBandVersion)_$(var.NetCorePlatform)?>
26 <?define DotNetCoreSdkRedistLog = DotNetCoreRuntime$(var.NetCoreSdkIdVersion)RedistLog?> 26 <?define DotNetCoreSdkRedistId = DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist_$(var.NetCorePlatform)?>
27 <?define DotNetCoreSdkRedistLog = DotNetCoreSdk$(var.NetCoreSdkIdVersion)RedistLog?>
27 <?define DotNetCoreSdkRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?> 28 <?define DotNetCoreSdkRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?>
28 <?define DotNetCoreSdkRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?> 29 <?define DotNetCoreSdkRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreSdkRedistLog)]"?>
29 30
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/NetCore6.0.9_x64.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/NetCore6.0.9_x64.wxs
index e9ccdc51..0bf4cb35 100644
--- a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/NetCore6.0.9_x64.wxs
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/NetCore6.0.9_x64.wxs
@@ -5,7 +5,7 @@
5 <?define NetCorePlatform = x64?> 5 <?define NetCorePlatform = x64?>
6 <?define NetCoreIdVersion = 609?> 6 <?define NetCoreIdVersion = 609?>
7 <?define NetCoreVersion = 6.0.9?> 7 <?define NetCoreVersion = 6.0.9?>
8 <?define NetCoreSdkPlatform = x64?> 8 <?define NetCoreSdkFeatureBandVersion = 60400?>
9 <?define NetCoreSdkIdVersion = 60403?> 9 <?define NetCoreSdkIdVersion = 60403?>
10 <?define NetCoreSdkVersion = 6.0.403?> 10 <?define NetCoreSdkVersion = 6.0.403?>
11 <?include ..\TestBAWixlib\NetCore6_Platform.wxi?> 11 <?include ..\TestBAWixlib\NetCore6_Platform.wxi?>
@@ -61,16 +61,21 @@
61 </Fragment> 61 </Fragment>
62 62
63 <Fragment> 63 <Fragment>
64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCoreSdkPlatform)" Version="6.0.200" Variable="$(var.DotNetCoreSdkId)" /> 64 <netfx:DotNetCoreSdkSearch Id="$(var.DotNetCoreSdkId)" Platform="$(var.NetCorePlatform)" MajorVersion="6" Variable="$(var.DotNetCoreSdkId)" />
65 <netfx:DotNetCoreSdkFeatureBandSearch Id="$(var.DotNetCoreSdkFeatureBandId)" Platform="$(var.NetCorePlatform)" Version="6.0.400" Variable="$(var.DotNetCoreSdkFeatureBandId)" />
66 </Fragment>
67
68 <Fragment>
69 <netfx:DotNetCoreSdkFeatureBandSearchRef Id="$(var.DotNetCoreSdkFeatureBandId)" />
65 70
66 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition" Value="$(var.DotNetCoreSdkId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" /> 71 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition" Value="$(var.DotNetCoreSdkFeatureBandId) &gt;= v$(var.NetCoreSdkVersion)" Overridable="yes" />
67 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition" Value="" Overridable="yes" /> 72 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition" Value="" Overridable="yes" />
68 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory" Value="redist\" Overridable="yes" /> 73 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory" Value="redist\" Overridable="yes" />
69 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)RepairArguments" Value="" Overridable="yes" /> 74 <WixVariable Id="DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
70 75
71 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)"> 76 <PackageGroup Id="$(var.DotNetCoreSdkRedistId)">
72 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove"> 77 <ExePackage CacheId="$(var.DotNetCoreSdkRedistId)_2485A7AFA98E178CB8F30C9838346B514AEA4769" InstallArguments="$(var.DotNetCoreSdkRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DotNetCoreSdkRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DotNetCoreSdkRedistLog)" Cache="remove">
73 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCoreSdkPlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCoreSdkPlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET 6.0 SDK - 6.0.403 (x64)" Description="Microsoft .NET SDK - 6.0.403 (x64)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="205722192" Version="6.0.403" /> 78 <ExePackagePayload Name="!(wix.DotNetCoreSdk$(var.NetCoreSdkIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)dotnet-sdk-$(var.NetCoreSdkVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.DotNetCoreSdkRedistLink)" ProductName="Microsoft .NET 6.0 SDK - 6.0.403 (x64)" Description="Microsoft .NET SDK - 6.0.403 (x64)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Size="205722192" Version="6.0.403" />
74 </ExePackage> 79 </ExePackage>
75 </PackageGroup> 80 </PackageGroup>
76 </Fragment> 81 </Fragment>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/WixBA_x64.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/WixBA_x64.wxs
index 6cfbc937..e9cd9827 100644
--- a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/WixBA_x64.wxs
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/WixBA_x64.wxs
@@ -1,5 +1,5 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> 1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:netfx="http://wixtoolset.org/schemas/v4/wxs/netfx">
3 <Fragment> 3 <Fragment>
4 <BootstrapperApplication> 4 <BootstrapperApplication>
5 <Payload SourceFile="!(bindpath.dncx64)\WixToolset.WixBA.deps.json" /> 5 <Payload SourceFile="!(bindpath.dncx64)\WixToolset.WixBA.deps.json" />
@@ -14,5 +14,7 @@
14 <PackageGroup Id="WixBAdnc_x64"> 14 <PackageGroup Id="WixBAdnc_x64">
15 <PackageGroupRef Id="DesktopNetCoreRuntime609Redist_x64AsPrereq" /> 15 <PackageGroupRef Id="DesktopNetCoreRuntime609Redist_x64AsPrereq" />
16 </PackageGroup> 16 </PackageGroup>
17
18 <netfx:DotNetCoreSdkSearchRef Id="DOTNETCORESDK6_x64" />
17 </Fragment> 19 </Fragment>
18</Wix> 20</Wix>