Skip to content

Commit add78b4

Browse files
committed
Adding installer UI w/ licence text and completion message
1 parent c75d220 commit add78b4

File tree

6 files changed

+93
-65
lines changed

6 files changed

+93
-65
lines changed

ReadableExpressions.Visualizers.Installer.Custom/RegistryData.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,10 @@ public IEnumerable<Visualizer> GetInstallableVisualizersFor(Visualizer visualize
7373
var indexOfIde = vsInstallPath.IndexOf("IDE", StringComparison.OrdinalIgnoreCase);
7474
var pathToCommon7 = vsInstallPath.Substring(0, indexOfIde);
7575
var pathToVisualizers = Path.Combine(pathToCommon7, "Packages", "Debugger", "Visualizers");
76-
var visualizerAssemblyName = GetResourceFileName(targetVisualizer.ResourceName);
7776
var pathToExtensions = GetPathToExtensions(vsInstallPath);
7877

79-
targetVisualizer.InstallPath = Path.Combine(pathToVisualizers, visualizerAssemblyName);
80-
targetVisualizer.VsixManifestPath = Path.Combine(pathToExtensions, "extension.vsixmanifest");
81-
78+
targetVisualizer.SetInstallPath(pathToVisualizers);
79+
targetVisualizer.SetVsixManifestPath(pathToExtensions);
8280
targetVisualizer.PopulateVsSetupData();
8381

8482
yield return targetVisualizer;
@@ -134,14 +132,6 @@ private void PopulatePost2015InstallPaths(
134132
}
135133
}
136134

137-
private static string GetResourceFileName(string resourceName)
138-
{
139-
var resourceAssemblyNameLength = (typeof(Visualizer).Namespace?.Length + 1).GetValueOrDefault();
140-
var resourceFileName = resourceName.Substring(resourceAssemblyNameLength);
141-
142-
return resourceFileName;
143-
}
144-
145135
private string GetPathToExtensions(string vsInstallPath)
146136
{
147137
return Path.Combine(

ReadableExpressions.Visualizers.Installer.Custom/Visualizer.cs

Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Reflection;
88
using System.Text;
9+
using System.Text.RegularExpressions;
910
using Microsoft.Win32;
1011

1112
internal class Visualizer : IDisposable
@@ -15,76 +16,113 @@ internal class Visualizer : IDisposable
1516
private readonly Action<string> _logger;
1617
private readonly Version _version;
1718
private readonly string _vsixManifest;
19+
private RegistryKey _registryKey;
20+
private string _vsExePath;
21+
private string _vsSetupArgument;
22+
private string _installPath;
23+
private string _vsixManifestPath;
24+
25+
public Visualizer(
26+
Action<string> logger,
27+
FileVersionInfo version,
28+
string vsixManifest,
29+
string resourceName)
30+
: this(logger, new Version(version.FileVersion), vsixManifest, resourceName, GetVsVersionNumber(resourceName))
31+
{
32+
}
33+
34+
#region Setup
1835

19-
public Visualizer(Action<string> logger, FileVersionInfo version, string vsixManifest)
20-
: this(logger, new Version(version.FileVersion), vsixManifest)
36+
private static readonly Regex _versionNumberMatcher =
37+
new Regex(@"Vs(?<VersionNumber>[\d]+)\.dll$", RegexOptions.IgnoreCase);
38+
39+
private static int GetVsVersionNumber(string resourceName)
2140
{
41+
var matchValue = _versionNumberMatcher
42+
.Match(resourceName)
43+
.Groups["VersionNumber"]
44+
.Value;
45+
46+
return int.Parse(matchValue);
2247
}
2348

24-
private Visualizer(Action<string> logger, Version version, string vsixManifest)
49+
#endregion
50+
51+
private Visualizer(
52+
Action<string> logger,
53+
Version version,
54+
string vsixManifest,
55+
string resourceName,
56+
int vsVersionNumber)
2557
{
2658
_logger = logger;
2759
_version = version;
2860
_vsixManifest = vsixManifest;
61+
ResourceName = resourceName;
62+
VsVersionNumber = vsVersionNumber;
2963
}
3064

31-
public int VsVersionNumber { get; set; }
65+
public int VsVersionNumber { get; }
3266

3367
public string VsFullVersionNumber => VsVersionNumber + ".0";
3468

35-
public string ResourceName { get; set; }
36-
37-
public RegistryKey RegistryKey { get; set; }
69+
public string ResourceName { get; }
3870

39-
public string VsInstallDirectory { get; set; }
71+
public string GetResourceFileName()
72+
{
73+
var resourceAssemblyNameLength = (typeof(Visualizer).Namespace?.Length + 1).GetValueOrDefault();
74+
var resourceFileName = ResourceName.Substring(resourceAssemblyNameLength);
4075

41-
public string InstallPath { get; set; }
76+
return resourceFileName;
77+
}
4278

43-
public string VsixManifestPath { get; set; }
79+
public string VsInstallDirectory { get; private set; }
4480

45-
public string VsExePath { get; set; }
81+
public void SetInstallPath(string pathToVisualizers)
82+
=> _installPath = Path.Combine(pathToVisualizers, GetResourceFileName());
4683

47-
public string VsSetupArgument { get; set; }
84+
public void SetVsixManifestPath(string pathToExtensions)
85+
=> _vsixManifestPath = Path.Combine(pathToExtensions, "extension.vsixmanifest");
4886

4987
public void Install()
5088
{
5189
// ReSharper disable once AssignNullToNotNullAttribute
52-
if (!Directory.Exists(Path.GetDirectoryName(InstallPath)))
90+
if (!Directory.Exists(Path.GetDirectoryName(_installPath)))
5391
{
54-
Log("Skipping as directory does not exist: " + InstallPath);
92+
Log("Skipping as directory does not exist: " + _installPath);
5593
return;
5694
}
5795

5896
using (var resourceStream = _thisAssembly.GetManifestResourceStream(ResourceName))
59-
using (var visualizerFileStream = File.OpenWrite(InstallPath))
97+
using (var visualizerFileStream = File.OpenWrite(_installPath))
6098
{
61-
Log("Writing visualizer to " + InstallPath);
99+
Log("Writing visualizer to " + _installPath);
62100
// ReSharper disable once PossibleNullReferenceException
63101
resourceStream.CopyTo(visualizerFileStream);
64102
}
65103

66-
var manifestDirectory = Path.GetDirectoryName(VsixManifestPath);
104+
var manifestDirectory = Path.GetDirectoryName(_vsixManifestPath);
67105

68-
Log("Writing manifest to " + VsixManifestPath);
106+
Log("Writing manifest to " + _vsixManifestPath);
69107
// ReSharper disable once AssignNullToNotNullAttribute
70108
Directory.CreateDirectory(manifestDirectory);
71-
File.WriteAllText(VsixManifestPath, _vsixManifest, Encoding.ASCII);
109+
File.WriteAllText(_vsixManifestPath, _vsixManifest, Encoding.ASCII);
72110

73111
ResetVsExtensions();
74112
}
75113

76114
public DirectoryInfo GetVsixManifestDirectory()
77115
{
78116
// ReSharper disable once AssignNullToNotNullAttribute
79-
return new DirectoryInfo(Path.GetDirectoryName(VsixManifestPath));
117+
return new DirectoryInfo(Path.GetDirectoryName(_vsixManifestPath));
80118
}
81119

82120
public void Uninstall()
83121
{
84122
DeletePreviousManifests();
85123

86124
// ReSharper disable PossibleNullReferenceException
87-
if (File.Exists(VsixManifestPath))
125+
if (File.Exists(_vsixManifestPath))
88126
{
89127
var vsixManifestDirectory = GetVsixManifestDirectory();
90128
var productDirectory = vsixManifestDirectory.Parent;
@@ -109,9 +147,9 @@ public void Uninstall()
109147
}
110148
// ReSharper restore PossibleNullReferenceException
111149

112-
if (File.Exists(InstallPath))
150+
if (File.Exists(_installPath))
113151
{
114-
File.Delete(InstallPath);
152+
File.Delete(_installPath);
115153
}
116154
}
117155

@@ -140,13 +178,13 @@ private void DeletePreviousManifests()
140178

141179
private void ResetVsExtensions()
142180
{
143-
if (VsExePath == null)
181+
if (_vsExePath == null)
144182
{
145183
return;
146184
}
147185

148-
Log("Updating VS extension records using " + VsExePath);
149-
using (Process.Start(VsExePath, VsSetupArgument)) { }
186+
Log("Updating VS extension records using " + _vsExePath);
187+
using (Process.Start(_vsExePath, _vsSetupArgument)) { }
150188
}
151189

152190
public void PopulateVsSetupData()
@@ -158,23 +196,21 @@ public void PopulateVsSetupData()
158196
return;
159197
}
160198

161-
VsExePath = pathToDevEnv;
162-
VsSetupArgument = RegistryKey?.GetValue("SetupCommandLine") as string ?? "/setup";
199+
_vsExePath = pathToDevEnv;
200+
_vsSetupArgument = _registryKey?.GetValue("SetupCommandLine") as string ?? "/setup";
163201
}
164202

165203
public Visualizer With(RegistryKey registryKey, string vsInstallPath)
166204
{
167-
return new Visualizer(_logger, _version, _vsixManifest)
205+
return new Visualizer(_logger, _version, _vsixManifest, ResourceName, VsVersionNumber)
168206
{
169-
VsVersionNumber = VsVersionNumber,
170-
ResourceName = ResourceName,
171-
RegistryKey = registryKey,
207+
_registryKey = registryKey,
172208
VsInstallDirectory = vsInstallPath
173209
};
174210
}
175211

176212
private void Log(string message) => _logger.Invoke(message);
177213

178-
public void Dispose() => RegistryKey?.Dispose();
214+
public void Dispose() => _registryKey?.Dispose();
179215
}
180216
}

ReadableExpressions.Visualizers.Installer.Custom/VisualizerInstallationActions.cs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ namespace AgileObjects.ReadableExpressions.Visualizers.Installer.Custom
66
using System.IO;
77
using System.Linq;
88
using System.Reflection;
9-
using System.Text.RegularExpressions;
109
using Microsoft.Deployment.WindowsInstaller;
1110

1211
public class VisualizerInstallationActions
@@ -60,21 +59,27 @@ private static string GetVsixManifest()
6059
public static ActionResult Install(Session session)
6160
{
6261
#if DEBUG
63-
Debugger.Launch();
62+
Debugger.Break();
6463
#endif
6564
_session = session;
6665

6766
try
6867
{
68+
var installed = new List<string> { "Installed visualizers for:" };
69+
6970
Log("Starting...");
7071

7172
foreach (var visualizer in GetRelevantVisualizers())
7273
{
7374
Log("Installing visualizer " + visualizer.ResourceName + "...");
7475
visualizer.Uninstall();
7576
visualizer.Install();
77+
78+
installed.Add("Visual Studio " + visualizer.VsFullVersionNumber);
7679
}
7780

81+
session["WIXUI_EXITDIALOGOPTIONALTEXT"] = string.Join(Environment.NewLine, installed);
82+
7883
Log("Complete");
7984

8085
return ActionResult.Success;
@@ -120,29 +125,12 @@ private static IEnumerable<Visualizer> GetRelevantVisualizers()
120125
return _thisAssembly
121126
.GetManifestResourceNames()
122127
.WithExtension("dll")
123-
.Select(visualizerResourceName => new Visualizer(Log, _thisAssemblyVersion, VsixManifest)
124-
{
125-
ResourceName = visualizerResourceName,
126-
VsVersionNumber = GetVsVersionNumber(visualizerResourceName)
127-
})
128+
.Select(visualizerResourceName => new Visualizer(Log, _thisAssemblyVersion, VsixManifest, visualizerResourceName))
128129
.SelectMany(visualizer => registryData.GetInstallableVisualizersFor(visualizer))
129130
.ToArray();
130131
}
131132
}
132133

133-
private static readonly Regex _versionNumberMatcher =
134-
new Regex(@"Vs(?<VersionNumber>[\d]+)\.dll$", RegexOptions.IgnoreCase);
135-
136-
private static int GetVsVersionNumber(string visualizerResourceName)
137-
{
138-
var matchValue = _versionNumberMatcher
139-
.Match(visualizerResourceName)
140-
.Groups["VersionNumber"]
141-
.Value;
142-
143-
return int.Parse(matchValue);
144-
}
145-
146134
private static void Log(string message) => _session?.Log(message);
147135
}
148136
}

ReadableExpressions.Visualizers.Installer/Product.wxs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
33
<Product Id="*" Version="1.12.1.0" Name="AgileObjects.ReadableExpressions.Visualizers"
44
Language="1033" Manufacturer="AgileObjects" UpgradeCode="BB7C528F-ECFD-45F2-B50C-9F0A71EC8BE9">
5+
56
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
67

8+
<UIRef Id="WixUI_Minimal" />
9+
<WixVariable Id="WixUILicenseRtf" Value=".\license.rtf" />
10+
<Property Id="WIXUI_EXITDIALOGOPTIONALTEXT" Value="Install complete" />
11+
712
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
813
<MediaTemplate />
914

ReadableExpressions.Visualizers.Installer/ReadableExpressions.Visualizers.Installer.wixproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
3232
</ProjectReference>
3333
</ItemGroup>
34+
<ItemGroup>
35+
<WixExtension Include="WixUIExtension">
36+
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
37+
<Name>WixUIExtension</Name>
38+
</WixExtension>
39+
</ItemGroup>
40+
<ItemGroup>
41+
<Content Include="license.rtf" />
42+
</ItemGroup>
3443
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
3544
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
3645
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
1.32 KB
Binary file not shown.

0 commit comments

Comments
 (0)