Skip to content

Commit 5c40fa7

Browse files
committed
notify windows users that packages may not extract properly, advise to run as admin or turn developer mode on.
1 parent 544d7ef commit 5c40fa7

File tree

4 files changed

+89
-11
lines changed

4 files changed

+89
-11
lines changed

Diff for: AvalonStudio/AvalonStudio.Extensibility/Platforms/Platform.cs

-2
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,11 @@ public static char DirectorySeperator
329329
public static string OSDescription => RuntimeInformation.OSDescription;
330330

331331
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
332-
333332
internal static extern byte CreateSymbolicLinkW(string lpSymlinkFileName, string lpTargetFileName, uint dwFlags);
334333

335334
internal const uint SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 2;
336335

337336
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
338-
339337
internal static extern byte CreateHardLinkW(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
340338

341339
public static bool CreateSymbolicLinkWin32(string linkName, string target, bool isFile)

Diff for: AvalonStudio/PackageManager/PackageManager.cs

+87-8
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
using Newtonsoft.Json.Linq;
1212
using System;
1313
using System.Collections.Generic;
14+
using System.Diagnostics;
1415
using System.IO;
1516
using System.Linq;
1617
using System.Runtime.InteropServices;
18+
using System.Security.Principal;
1719
using System.Threading;
1820
using System.Threading.Tasks;
1921

@@ -113,16 +115,87 @@ public static async Task<IList<string>> ListToolchains()
113115
return await ListPackages("toolchain");
114116
}
115117

118+
private static bool s_isAdministrator;
119+
private static bool s_hasPerformedCheck;
120+
private static object s_adminCheckLock = new object();
121+
122+
private static bool CanExtract ()
123+
{
124+
if (!s_isAdministrator && !s_hasPerformedCheck && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
125+
{
126+
lock (s_adminCheckLock)
127+
{
128+
var testFile = Path.Combine(Platform.PackageDirectory, "testlink");
129+
var linkPath = Path.Combine(Platform.PackageDirectory, "symlink");
130+
131+
bool result = false;
132+
133+
if (File.Exists(testFile))
134+
{
135+
File.Delete(testFile);
136+
}
137+
138+
if (File.Exists(linkPath))
139+
{
140+
File.Delete(linkPath);
141+
}
142+
143+
using (File.CreateText(testFile))
144+
{
145+
result = Platform.CreateSymbolicLinkWin32(linkPath, testFile, true);
146+
147+
if (result)
148+
{
149+
s_isAdministrator = true;
150+
}
151+
152+
s_hasPerformedCheck = true;
153+
}
154+
155+
if (File.Exists(testFile))
156+
{
157+
File.Delete(testFile);
158+
}
159+
160+
if (File.Exists(linkPath))
161+
{
162+
File.Delete(linkPath);
163+
}
164+
165+
return result;
166+
}
167+
}
168+
169+
s_hasPerformedCheck = true;
170+
171+
return true;
172+
}
173+
174+
private static bool EnsureAdminCanExtract (IConsole console)
175+
{
176+
var result = CanExtract();
177+
178+
if(!result)
179+
{
180+
console?.WriteLine("Unable to install packages, run as administrator on Windows or enable developer mode and try again.");
181+
}
182+
183+
return result;
184+
}
185+
116186

117187
public static void ExtractAllToolchainPackages (IConsole console = null)
118188
{
119-
foreach (var package in Directory.EnumerateDirectories(Platform.PackageDirectory))
189+
if (EnsureAdminCanExtract(console))
120190
{
121-
foreach(var version in Directory.EnumerateDirectories(package))
191+
foreach (var package in Directory.EnumerateDirectories(Platform.PackageDirectory))
122192
{
123-
foreach (var archive in Directory.EnumerateFiles(version, "*.avpkg"))
193+
foreach (var version in Directory.EnumerateDirectories(package))
124194
{
125-
UnpackArchive(archive, version, (offset, length) => console?.OverWrite($"Extracting: [{(((float)offset / length) * 100.0f).ToString("0.00")}%])"), true);
195+
foreach (var archive in Directory.EnumerateFiles(version, "*.avpkg"))
196+
{
197+
UnpackArchive(archive, version, (offset, length) => console?.OverWrite($"Extracting: [{(((float)offset / length) * 100.0f).ToString("0.00")}%])"), true);
198+
}
126199
}
127200
}
128201
}
@@ -367,6 +440,7 @@ private static void UnpackArchive(string archiveFileName, string targetDirectory
367440
if (!File.Exists(archiveFileName))
368441
throw new FileNotFoundException("Archive not found.", archiveFileName);
369442

443+
370444
// Ensure that the target directory exists.
371445
Directory.CreateDirectory(targetDirectory);
372446

@@ -543,7 +617,7 @@ private static void ExtractTarByEntry(Stream inputStream, string targetDir, bool
543617
case '2':
544618
if (Platform.PlatformIdentifier == Platforms.PlatformID.Win32NT)
545619
{
546-
Platform.CreateSymbolicLinkWin32(outName.NormalizePath(), tarEntry.TarHeader.LinkName, !tarEntry.IsDirectory);
620+
Platform.CreateSymbolicLinkWin32(outName.NormalizePath(), tarEntry.TarHeader.LinkName.NormalizePath(), !tarEntry.IsDirectory);
547621
}
548622
else
549623
{
@@ -634,12 +708,12 @@ public static async Task InstallPackage(Package package, Action<long, long> prog
634708
await Task.Run(() =>
635709
{
636710
var archivePath = Path.Combine(Platform.PackageDirectory, package.Name, package.Version.ToString());
637-
711+
638712
UnpackArchive(Path.Combine(archivePath, package.BlobIdentity), archivePath, progress, true);
639713

640714
if (!CICacheMode)
641715
{
642-
File.Delete(Path.Combine(archivePath, package.BlobIdentity));
716+
File.Delete(Path.Combine(archivePath, package.BlobIdentity));
643717
}
644718
});
645719
}
@@ -651,7 +725,12 @@ public static Task<PackageEnsureStatus> EnsurePackage(string packageName, IConso
651725

652726
public static async Task<PackageEnsureStatus> EnsurePackage(string packageName, string version, IConsole console)
653727
{
654-
packageName = packageName.ToLower();
728+
if (!EnsureAdminCanExtract(console))
729+
{
730+
return PackageEnsureStatus.Unknown;
731+
}
732+
733+
packageName = packageName.ToLower();
655734

656735
if (string.IsNullOrWhiteSpace(packageName))
657736
{

Diff for: AvalonStudio/PackageManager/PackageManager.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<ItemGroup>
1818
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
1919
<PackageReference Include="SharpZipLib" Version="1.2.0" />
20+
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
2021
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
2122
</ItemGroup>
2223

0 commit comments

Comments
 (0)