Skip to content

Commit 8fdee31

Browse files
authored
Fix deployment issue with repeated assemblies (#324)
1 parent 38f5b83 commit 8fdee31

File tree

4 files changed

+69
-11
lines changed

4 files changed

+69
-11
lines changed

source/VisualStudio.Extension/DeployProvider/DeployProvider.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,21 @@ await ReferenceCrawler.CollectAssembliesToDeployAsync(
193193
Properties.ConfiguredProject);
194194

195195
// build a list with the full path for each DLL, referenced DLL and EXE
196-
List<(string path, string version)> assemblyList = new List<(string path, string version)>();
196+
List<DeploymentAssembly> assemblyList = new List<DeploymentAssembly>();
197197

198198
foreach (string assemblyPath in assemblyPathsToDeploy)
199199
{
200200
// load assembly to get the version
201201
var assembly = Assembly.Load(File.ReadAllBytes(assemblyPath)).GetName();
202-
assemblyList.Add((assemblyPath, $"{assembly.Version.ToString(4)}"));
202+
assemblyList.Add(new DeploymentAssembly(assemblyPath, $"{assembly.Version.ToString(4)}"));
203203
}
204204

205205
// if there are referenced project, the assembly list contains repeated assemblies so need to use Linq Distinct()
206+
// an IEqualityComparer is required implementing the proper comparison
207+
List<DeploymentAssembly> distinctAssemblyList = assemblyList.Distinct(new DeploymentAssemblyDistinctEquality()).ToList();
208+
206209
// build a list with the PE files corresponding to each DLL and EXE
207-
List<(string path, string version)> peCollection = assemblyList.Distinct().Select(a => (a.path.Replace(".dll", ".pe").Replace(".exe", ".pe"), a.version)).ToList();
210+
List<DeploymentAssembly> peCollection = distinctAssemblyList.Select(a => new DeploymentAssembly(a.Path.Replace(".dll", ".pe").Replace(".exe", ".pe"), a.Version)).ToList();
208211

209212
var checkAssembliesResult = await CheckNativeAssembliesAvailabilityAsync(device.DeviceInfo.NativeAssemblies, peCollection);
210213
if (checkAssembliesResult != "")
@@ -217,13 +220,13 @@ await ReferenceCrawler.CollectAssembliesToDeployAsync(
217220
long totalSizeOfAssemblies = 0;
218221

219222
// now we will re-deploy all system assemblies
220-
foreach ((string path, string version) peItem in peCollection)
223+
foreach (DeploymentAssembly peItem in peCollection)
221224
{
222225
// append to the deploy blob the assembly
223-
using (FileStream fs = File.Open(peItem.path, FileMode.Open, FileAccess.Read))
226+
using (FileStream fs = File.Open(peItem.Path, FileMode.Open, FileAccess.Read))
224227
{
225228
long length = (fs.Length + 3) / 4 * 4;
226-
await outputPaneWriter.WriteLineAsync($"Adding {Path.GetFileNameWithoutExtension(peItem.path)} v{peItem.version} ({length.ToString()} bytes) to deployment bundle");
229+
await outputPaneWriter.WriteLineAsync($"Adding {Path.GetFileNameWithoutExtension(peItem.Path)} v{peItem.Version} ({length.ToString()} bytes) to deployment bundle");
227230
byte[] buffer = new byte[length];
228231

229232
await fs.ReadAsync(buffer, 0, (int)fs.Length);
@@ -277,15 +280,15 @@ await ReferenceCrawler.CollectAssembliesToDeployAsync(
277280
}
278281
}
279282

280-
private async System.Threading.Tasks.Task<string> CheckNativeAssembliesAvailabilityAsync(List<CLRCapabilities.NativeAssemblyProperties> nativeAssemblies, List<(string path, string version)> peCollection)
283+
private async System.Threading.Tasks.Task<string> CheckNativeAssembliesAvailabilityAsync(List<CLRCapabilities.NativeAssemblyProperties> nativeAssemblies, List<DeploymentAssembly> peCollection)
281284
{
282285
string errorMessage = string.Empty;
283286

284287
// loop through each PE to deploy...
285288
foreach (var peItem in peCollection)
286289
{
287290
// open the PE file and load content
288-
using (FileStream fs = File.Open(peItem.path, FileMode.Open, FileAccess.Read))
291+
using (FileStream fs = File.Open(peItem.Path, FileMode.Open, FileAccess.Read))
289292
{
290293
// get PE checksum
291294
byte[] buffer = new byte[4];
@@ -305,7 +308,7 @@ private async System.Threading.Tasks.Task<string> CheckNativeAssembliesAvailabil
305308
var nativeAssembly = nativeAssemblies.Find(a => a.Checksum == peChecksum);
306309

307310
// check the version now
308-
if (nativeAssembly.Version.ToString(4) == peItem.version)
311+
if (nativeAssembly.Version.ToString(4) == peItem.Version)
309312
{
310313
// we are good with this one
311314
continue;
@@ -323,7 +326,7 @@ private async System.Threading.Tasks.Task<string> CheckNativeAssembliesAvailabil
323326
exceptionAssemblies.Add(new CLRCapabilities.NativeAssemblyProperties("Windows.Storage.Streams", 0, new Version()));
324327
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
325328

326-
if (exceptionAssemblies.Exists(a => a.Name == Path.GetFileNameWithoutExtension(peItem.path)))
329+
if (exceptionAssemblies.Exists(a => a.Name == Path.GetFileNameWithoutExtension(peItem.Path)))
327330
{
328331
// we are good with this one
329332
continue;
@@ -338,7 +341,7 @@ private async System.Threading.Tasks.Task<string> CheckNativeAssembliesAvailabil
338341
}
339342

340343
// no suitable native assembly found present a (hopefully) helpful message to the developer
341-
errorMessage += $"Couldn't find a valid native assembly required by {Path.GetFileNameWithoutExtension(peItem.path)} v{peItem.version}, checksum 0x{peChecksum.ToString("X8")}." + Environment.NewLine;
344+
errorMessage += $"Couldn't find a valid native assembly required by {Path.GetFileNameWithoutExtension(peItem.Path)} v{peItem.Version}, checksum 0x{peChecksum.ToString("X8")}." + Environment.NewLine;
342345
}
343346
}
344347

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Collections.Generic;
7+
8+
namespace nanoFramework.Tools.VisualStudio.Extension
9+
{
10+
public class DeploymentAssembly
11+
{
12+
public string Path { get; set; }
13+
public string Version { get; set; }
14+
15+
public DeploymentAssembly(string path, string version)
16+
{
17+
Path = path;
18+
Version = version;
19+
}
20+
}
21+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Collections.Generic;
7+
8+
namespace nanoFramework.Tools.VisualStudio.Extension
9+
{
10+
internal class DeploymentAssemblyDistinctEquality : IEqualityComparer<DeploymentAssembly>
11+
{
12+
public bool Equals(DeploymentAssembly assembly1, DeploymentAssembly assembly2)
13+
{
14+
var name1 = System.IO.Path.GetFileName(assembly1.Path);
15+
var name2 = System.IO.Path.GetFileName(assembly2.Path);
16+
17+
if ((name1 == name2) && (assembly1.Version == assembly2.Version))
18+
{
19+
return true;
20+
}
21+
else
22+
{
23+
return false;
24+
}
25+
}
26+
27+
public int GetHashCode(DeploymentAssembly assembly)
28+
{
29+
return System.IO.Path.GetFileName(assembly.Path).GetHashCode() ^ assembly.Version.GetHashCode();
30+
}
31+
}
32+
}

source/VisualStudio.Extension/VisualStudio.Extension.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@
102102
<Compile Include="CorDebug\Pdbx.cs" />
103103
<Compile Include="CorDebug\PdbxFile.cs" />
104104
<Compile Include="CorDebug\ProcessExitException.cs" />
105+
<Compile Include="DeployProvider\DeploymentAssembly.cs" />
106+
<Compile Include="DeployProvider\DeploymentAssemblyDistinctEquality.cs" />
105107
<Compile Include="DeployProvider\DeploymentException.cs" />
106108
<Compile Include="IPMaskedTextBox\IPMaskedTextBox.xaml.cs">
107109
<DependentUpon>IPMaskedTextBox.xaml</DependentUpon>

0 commit comments

Comments
 (0)