WIXFEAT:4009 - Add support for outbound firewall rule
adnan shaheen committed
Feb 5, 2018 at 14:01 UTC
5c851a848a6eeb86472e8a1cca814dd0cb1b0483
15 files changed
+142
-20
src/ca/firewall.cpp
+32
-14
@@ -3,7 +3,7 @@
3
#include "precomp.h"
4
5
LPCWSTR vcsFirewallExceptionQuery =
6
- L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description` FROM `WixFirewallException`";
6
+ L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction` FROM `WixFirewallException`";
7
enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription };
8
enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown };
9
enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 };
@@ -36,6 +36,7 @@ static UINT SchedFirewallExceptions(
36
LPWSTR pwzComponent = NULL;
37
LPWSTR pwzFormattedFile = NULL;
38
LPWSTR pwzDescription = NULL;
39
+ int iDirection = 0;
40
41
// initialize
42
hr = WcaInitialize(hInstall, "SchedFirewallExceptions");
@@ -130,6 +131,9 @@ static UINT SchedFirewallExceptions(
131
132
hr = WcaWriteStringToCaData(pwzDescription, &pwzCustomActionData);
133
ExitOnFailure(hr, "failed to write firewall rule description to custom action data");
134
+
135
+ hr = WcaWriteIntegerToCaData(iDirection, &pwzCustomActionData);
136
+ ExitOnFailure(hr, "failed to write firewall rule direction to custom action data");
137
}
138
139
// reaching the end of the list is actually a good thing, not an error
@@ -270,6 +274,7 @@ static HRESULT CreateFwRuleObject(
274
__in LPCWSTR wzPort,
275
__in int iProtocol,
276
__in LPCWSTR wzDescription,
277
+ __in int iDirection,
278
__out INetFwRule** ppNetFwRule
279
)
280
{
@@ -321,6 +326,12 @@ static HRESULT CreateFwRuleObject(
326
ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription);
327
}
328
329
+ if (MSI_NULL_INTEGER != iDirection)
330
+ {
331
+ hr = pNetFwRule->put_Direction(static_cast<NET_FW_RULE_DIRECTION> (iDirection));
332
+ ExitOnFailure(hr, "failed to set exception direction");
333
+ }
334
+
335
*ppNetFwRule = pNetFwRule;
336
pNetFwRule = NULL;
337
@@ -429,7 +440,8 @@ static HRESULT AddApplicationException(
440
__in BOOL fIgnoreFailures,
441
__in LPCWSTR wzPort,
442
__in int iProtocol,
432
- __in LPCWSTR wzDescription
443
+ __in LPCWSTR wzDescription,
444
+ __in int iDirection
445
)
446
{
447
HRESULT hr = S_OK;
@@ -456,7 +468,7 @@ static HRESULT AddApplicationException(
468
hr = pNetFwRules->Item(bstrName, &pNetFwRule);
469
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
470
{
459
- hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, &pNetFwRule);
471
+ hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, iDirection, &pNetFwRule);
472
ExitOnFailure(hr, "failed to create FwRule object");
473
474
// set edge traversal to true
@@ -590,8 +602,9 @@ static HRESULT AddPortException(
602
__in BOOL fIgnoreFailures,
603
__in LPCWSTR wzPort,
604
__in int iProtocol,
593
- __in LPCWSTR wzDescription
594
- )
605
+ __in LPCWSTR wzDescription,
606
+ __in int iDirection
607
+)
608
{
609
HRESULT hr = S_OK;
610
BSTR bstrName = NULL;
@@ -614,7 +627,7 @@ static HRESULT AddPortException(
627
hr = pNetFwRules->Item(bstrName, &pNetFwRule);
628
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
629
{
617
- hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, &pNetFwRule);
630
+ hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, iDirection, &pNetFwRule);
631
ExitOnFailure(hr, "failed to create FwRule object");
632
633
// enable it
@@ -825,14 +838,15 @@ static HRESULT AddApplicationException(
838
__in BOOL fIgnoreFailures,
839
__in LPCWSTR wzPort,
840
__in int iProtocol,
828
- __in LPCWSTR wzDescription
829
- )
841
+ __in LPCWSTR wzDescription,
842
+ __in int iDirection
843
+)
844
{
845
HRESULT hr = S_OK;
846
847
if (fSupportProfiles)
848
{
835
- hr = AddApplicationException(wzFile, wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription);
849
+ hr = AddApplicationException(wzFile, wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription, iDirection);
850
}
851
else
852
{
@@ -860,14 +874,15 @@ static HRESULT AddPortException(
874
__in BOOL fIgnoreFailures,
875
__in LPCWSTR wzPort,
876
__in int iProtocol,
863
- __in LPCWSTR wzDescription
864
- )
877
+ __in LPCWSTR wzDescription,
878
+ __in int iDirection
879
+)
880
{
881
HRESULT hr = S_OK;
882
883
if (fSupportProfiles)
884
{
870
- hr = AddPortException(wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription);
885
+ hr = AddPortException(wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription, iDirection);
886
}
887
else
888
{
@@ -951,6 +966,7 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
966
LPWSTR pwzDescription = NULL;
967
int iProtocol = 0;
968
int iProfile = 0;
969
+ int iDirection = 0;
970
971
// initialize
972
hr = WcaInitialize(hInstall, "ExecFirewallExceptions");
@@ -1013,6 +1029,8 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
1029
ExitOnFailure(hr, "failed to read protocol from custom action data");
1030
hr = WcaReadStringFromCaData(&pwz, &pwzDescription);
1031
ExitOnFailure(hr, "failed to read protocol from custom action data");
1032
+ hr = WcaReadIntegerFromCaData(&pwz, &iDirection);
1033
+ ExitOnFailure(hr, "failed to read direction from custom action data");
1034
1035
switch (iTarget)
1036
{
@@ -1022,7 +1040,7 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
1040
case WCA_TODO_INSTALL:
1041
case WCA_TODO_REINSTALL:
1042
WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1025
- hr = AddPortException(fSupportProfiles, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription);
1043
+ hr = AddPortException(fSupportProfiles, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
1044
ExitOnFailure(hr, "failed to add/update port exception for name '%ls' on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1045
break;
1046
@@ -1040,7 +1058,7 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
1058
case WCA_TODO_INSTALL:
1059
case WCA_TODO_REINSTALL:
1060
WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls (%ls)", pwzName, pwzFile);
1043
- hr = AddApplicationException(fSupportProfiles, pwzFile, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription);
1061
+ hr = AddApplicationException(fSupportProfiles, pwzFile, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
1062
ExitOnFailure(hr, "failed to add/update application exception for name '%ls', file '%ls'", pwzName, pwzFile);
1063
break;
1064
src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
+15
-2
@@ -25,7 +25,7 @@ namespace WixToolsetTest.Firewall
25
"CustomAction:Wix4RollbackFirewallExceptionsUninstall_X86\t3329\tWix4FWCA_X86\tExecFirewallExceptions\t",
26
"CustomAction:Wix4SchedFirewallExceptionsInstall_X86\t1\tWix4FWCA_X86\tSchedFirewallExceptionsInstall\t",
27
"CustomAction:Wix4SchedFirewallExceptionsUninstall_X86\t1\tWix4FWCA_X86\tSchedFirewallExceptionsUninstall\t",
28
- "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall",
28
+ "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall\t1",
29
}, results);
30
}
31
@@ -44,7 +44,20 @@ namespace WixToolsetTest.Firewall
44
"CustomAction:Wix4RollbackFirewallExceptionsUninstall_A64\t3329\tWix4FWCA_A64\tExecFirewallExceptions\t",
45
"CustomAction:Wix4SchedFirewallExceptionsInstall_A64\t1\tWix4FWCA_A64\tSchedFirewallExceptionsInstall\t",
46
"CustomAction:Wix4SchedFirewallExceptionsUninstall_A64\t1\tWix4FWCA_A64\tSchedFirewallExceptionsUninstall\t",
47
- "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall",
47
+ "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall\t1",
48
+ }, results);
49
+ }
50
+
51
+ [Fact]
52
+ public void CanBuildUsingOutboundFirewall()
53
+ {
54
+ var folder = TestData.Get(@"TestData\UsingOutboundFirewall");
55
+ var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder });
56
+
57
+ var results = build.BuildAndQuery(Build, "WixFirewallException");
58
+ Assert.Equal(new[]
59
+ {
60
+ "WixFirewallException:fexPv9RR1kBvP6gMgWyXMVQkVbopOA\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example outbound firewall\t2",
61
}, results);
62
}
63
src/test/WixToolsetTest.Firewall/TestData/UsingOutboundFirewall/Package.en-us.wxl
new
+11
@@ -0,0 +1,11 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+
3
+<!--
4
+This file contains the declaration of all the localizable strings.
5
+-->
6
+<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
+
8
+ <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9
+ <String Id="FeatureTitle">MsiPackage</String>
10
+
11
+</WixLocalization>
src/test/WixToolsetTest.Firewall/TestData/UsingOutboundFirewall/Package.wxs
new
+22
@@ -0,0 +1,22 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Product Id="*" Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
4
+ <Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
5
+
6
+ <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
7
+ <MediaTemplate />
8
+
9
+ <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
10
+ <ComponentGroupRef Id="ProductComponents" />
11
+ </Feature>
12
+
13
+ </Product>
14
+
15
+ <Fragment>
16
+ <Directory Id="TARGETDIR" Name="SourceDir">
17
+ <Directory Id="ProgramFilesFolder">
18
+ <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
19
+ </Directory>
20
+ </Directory>
21
+ </Fragment>
22
+</Wix>
src/test/WixToolsetTest.Firewall/TestData/UsingOutboundFirewall/PackageComponents.wxs
new
+14
@@ -0,0 +1,14 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3
+ xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall">
4
+ <Fragment>
5
+ <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6
+ <Component>
7
+ <File Source="example.txt" />
8
+ <fw:FirewallException Description="An example outbound firewall" Name="example" Port="42" Outbound="yes">
9
+ <fw:RemoteAddress>*</fw:RemoteAddress>
10
+ </fw:FirewallException>
11
+ </Component>
12
+ </ComponentGroup>
13
+ </Fragment>
14
+</Wix>
src/test/WixToolsetTest.Firewall/TestData/UsingOutboundFirewall/example.txt
new
+1
@@ -0,0 +1 @@
1
+This is example.txt.
\ No newline at end of file
src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj
+4
@@ -16,6 +16,10 @@
16
<Content Include="TestData\UsingFirewall\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
17
<Content Include="TestData\UsingFirewall\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
18
<Content Include="TestData\UsingFirewall\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
19
+ <Content Include="TestData\UsingOutboundFirewall\example.txt" CopyToOutputDirectory="PreserveNewest" />
20
+ <Content Include="TestData\UsingOutboundFirewall\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
21
+ <Content Include="TestData\UsingOutboundFirewall\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
22
+ <Content Include="TestData\UsingOutboundFirewall\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
23
</ItemGroup>
24
25
<ItemGroup>
src/wixext/FirewallCompiler.cs
+7
@@ -81,6 +81,7 @@ namespace WixToolset.Firewall
81
string scope = null;
82
string remoteAddresses = null;
83
string description = null;
84
+ int? direction = null;
85
86
foreach (var attrib in element.Attributes())
87
{
@@ -177,6 +178,11 @@ namespace WixToolset.Firewall
178
case "Description":
179
description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
180
break;
181
+ case "Outbound":
182
+ direction = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes
183
+ ? FirewallConstants.NET_FW_RULE_DIR_OUT
184
+ : FirewallConstants.NET_FW_RULE_DIR_IN;
185
+ break;
186
default:
187
this.ParseHelper.UnexpectedAttribute(element, attrib);
188
break;
@@ -260,6 +266,7 @@ namespace WixToolset.Firewall
266
Profile = profile ?? FirewallConstants.NET_FW_PROFILE2_ALL,
267
ComponentRef = componentId,
268
Description = description,
269
+ Direction = direction ?? FirewallConstants.NET_FW_RULE_DIR_IN,
270
});
271
272
if (!String.IsNullOrEmpty(port))
src/wixext/FirewallConstants.cs
+2
@@ -9,6 +9,8 @@ namespace WixToolset.Firewall
9
static class FirewallConstants
10
{
11
// from icftypes.h
12
+ public const int NET_FW_RULE_DIR_IN = 1;
13
+ public const int NET_FW_RULE_DIR_OUT = 2;
14
public const int NET_FW_IP_PROTOCOL_TCP = 6;
15
public const int NET_FW_IP_PROTOCOL_UDP = 17;
16
src/wixext/FirewallDecompiler.cs
+13
@@ -146,6 +146,19 @@ namespace WixToolset.Firewall
146
fire.Description = (string)row[9];
147
}
148
149
+ if (!row.IsColumnEmpty(10))
150
+ {
151
+ switch (Convert.ToInt32(row[10]))
152
+ {
153
+ case FirewallConstants.NET_FW_RULE_DIR_IN:
154
+ fire.Direction = Firewall.FirewallException.DirectionType.@in;
155
+ break;
156
+ case FirewallConstants.NET_FW_RULE_DIR_OUT:
157
+ fire.Direction = Firewall.FirewallException.DirectionType.@out;
158
+ break;
159
+ }
160
+ }
161
+
162
Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[8]);
163
if (null != component)
164
{
src/wixext/FirewallTableDefinitions.cs
+1
@@ -21,6 +21,7 @@ namespace WixToolset.Firewall
21
new ColumnDefinition("Profile", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Integer, minValue: 1, maxValue: 2147483647, description: "Profile (1=domain; 2=private; 4=public; 2147483647=all)."),
22
new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing component that controls the firewall configuration.", modularizeType: ColumnModularizeType.Column),
23
new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."),
24
+ new ColumnDefinition("Direction", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 1, maxValue: 2, description: "Direction (1=in; 2=out)"),
25
},
26
tupleIdIsPrimaryKey: true
27
);
src/wixext/Tuples/WixFirewallExceptionTuple.cs
+8
@@ -20,6 +20,7 @@ namespace WixToolset.Firewall
20
new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number),
21
new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.ComponentRef), IntermediateFieldType.String),
22
new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String),
23
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Direction), IntermediateFieldType.Number),
24
},
25
typeof(WixFirewallExceptionTuple));
26
}
@@ -40,6 +41,7 @@ namespace WixToolset.Firewall.Tuples
41
Profile,
42
ComponentRef,
43
Description,
44
+ Direction,
45
}
46
47
public class WixFirewallExceptionTuple : IntermediateTuple
@@ -107,5 +109,11 @@ namespace WixToolset.Firewall.Tuples
109
get => this.Fields[(int)WixFirewallExceptionTupleFields.Description].AsString();
110
set => this.Set((int)WixFirewallExceptionTupleFields.Description, value);
111
}
112
+
113
+ public int Direction
114
+ {
115
+ get => this.Fields[(int)WixFirewallExceptionTupleFields.Direction].AsNumber();
116
+ set => this.Set((int)WixFirewallExceptionTupleFields.Direction, value);
117
+ }
118
}
119
}
\ No newline at end of file
src/wixext/firewall.xsd
+9
-1
@@ -141,7 +141,7 @@
141
<xs:attribute name="IgnoreFailure" type="YesNoType">
142
<xs:annotation>
143
<xs:documentation>
144
- If "yes," failures to register this firewall exception will be silently
144
+ If "yes", failures to register this firewall exception will be silently
145
ignored. If "no" (the default), failures will cause rollback.
146
</xs:documentation>
147
</xs:annotation>
@@ -170,6 +170,14 @@
170
</xs:documentation>
171
</xs:annotation>
172
</xs:attribute>
173
+
174
+ <xs:attribute name="Outbound" type="YesNoType">
175
+ <xs:annotation>
176
+ <xs:documentation>
177
+ If "yes", registers an outbound firewall rule.
178
+ </xs:documentation>
179
+ </xs:annotation>
180
+ </xs:attribute>
181
</xs:complexType>
182
</xs:element>
183
src/wixlib/firewall.wixproj
+2
-2
@@ -1,7 +1,7 @@
1
<?xml version="1.0" encoding="utf-8"?>
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
<Project DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
4
- <Import Project="..\..\packages\WixToolset.MSBuild.4.0.0-build-0093\build\WixToolset.MSBuild.props" Condition="Exists('..\..\packages\WixToolset.MSBuild.4.0.0-build-0093\build\WixToolset.MSBuild.props')" />
4
+ <Import Project="..\..\packages\WixToolset.MSBuild.4.0.0-build-0102\build\WixToolset.MSBuild.props" Condition="Exists('..\..\packages\WixToolset.MSBuild.4.0.0-build-0102\build\WixToolset.MSBuild.props')" />
5
<Import Project="..\FindLocalWix.props" />
6
<PropertyGroup>
7
<ProjectGuid>{1acffefd-505a-41a5-acbf-a02b7b473aa2}</ProjectGuid>
@@ -73,7 +73,7 @@
73
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
74
</PropertyGroup>
75
<Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets'))" />
76
- <Error Condition="!Exists('..\..\packages\WixToolset.MSBuild.4.0.0-build-0093\build\WixToolset.MSBuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.MSBuild.4.0.0-build-0093\build\WixToolset.MSBuild.props'))" />
76
+ <Error Condition="!Exists('..\..\packages\WixToolset.MSBuild.4.0.0-build-0102\build\WixToolset.MSBuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.MSBuild.4.0.0-build-0102\build\WixToolset.MSBuild.props'))" />
77
</Target>
78
<Import Project="..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets" Condition="Exists('..\..\packages\Nerdbank.GitVersioning.2.1.65\build\Nerdbank.GitVersioning.targets')" />
79
</Project>
\ No newline at end of file
src/wixlib/packages.config
+1
-1
@@ -1,5 +1,5 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<packages>
3
<package id="Nerdbank.GitVersioning" version="2.1.65" developmentDependency="true" targetFramework="net40" />
4
- <package id="WixToolset.MSBuild" version="4.0.0-build-0093" developmentDependency="true" targetFramework="net40" />
4
+ <package id="WixToolset.MSBuild" version="4.0.0-build-0102" developmentDependency="true" targetFramework="net40" />
5
</packages>
\ No newline at end of file