11
11
using Newtonsoft . Json . Linq ;
12
12
using System ;
13
13
using System . Collections . Generic ;
14
+ using System . Diagnostics ;
14
15
using System . IO ;
15
16
using System . Linq ;
16
17
using System . Runtime . InteropServices ;
18
+ using System . Security . Principal ;
17
19
using System . Threading ;
18
20
using System . Threading . Tasks ;
19
21
@@ -113,16 +115,87 @@ public static async Task<IList<string>> ListToolchains()
113
115
return await ListPackages ( "toolchain" ) ;
114
116
}
115
117
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
+
116
186
117
187
public static void ExtractAllToolchainPackages ( IConsole console = null )
118
188
{
119
- foreach ( var package in Directory . EnumerateDirectories ( Platform . PackageDirectory ) )
189
+ if ( EnsureAdminCanExtract ( console ) )
120
190
{
121
- foreach ( var version in Directory . EnumerateDirectories ( package ) )
191
+ foreach ( var package in Directory . EnumerateDirectories ( Platform . PackageDirectory ) )
122
192
{
123
- foreach ( var archive in Directory . EnumerateFiles ( version , "*.avpkg" ) )
193
+ foreach ( var version in Directory . EnumerateDirectories ( package ) )
124
194
{
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
+ }
126
199
}
127
200
}
128
201
}
@@ -367,6 +440,7 @@ private static void UnpackArchive(string archiveFileName, string targetDirectory
367
440
if ( ! File . Exists ( archiveFileName ) )
368
441
throw new FileNotFoundException ( "Archive not found." , archiveFileName ) ;
369
442
443
+
370
444
// Ensure that the target directory exists.
371
445
Directory . CreateDirectory ( targetDirectory ) ;
372
446
@@ -543,7 +617,7 @@ private static void ExtractTarByEntry(Stream inputStream, string targetDir, bool
543
617
case '2' :
544
618
if ( Platform . PlatformIdentifier == Platforms . PlatformID . Win32NT )
545
619
{
546
- Platform . CreateSymbolicLinkWin32 ( outName . NormalizePath ( ) , tarEntry . TarHeader . LinkName , ! tarEntry . IsDirectory ) ;
620
+ Platform . CreateSymbolicLinkWin32 ( outName . NormalizePath ( ) , tarEntry . TarHeader . LinkName . NormalizePath ( ) , ! tarEntry . IsDirectory ) ;
547
621
}
548
622
else
549
623
{
@@ -634,12 +708,12 @@ public static async Task InstallPackage(Package package, Action<long, long> prog
634
708
await Task . Run ( ( ) =>
635
709
{
636
710
var archivePath = Path . Combine ( Platform . PackageDirectory , package . Name , package . Version . ToString ( ) ) ;
637
-
711
+
638
712
UnpackArchive ( Path . Combine ( archivePath , package . BlobIdentity ) , archivePath , progress , true ) ;
639
713
640
714
if ( ! CICacheMode )
641
715
{
642
- File . Delete ( Path . Combine ( archivePath , package . BlobIdentity ) ) ;
716
+ File . Delete ( Path . Combine ( archivePath , package . BlobIdentity ) ) ;
643
717
}
644
718
} ) ;
645
719
}
@@ -651,7 +725,12 @@ public static Task<PackageEnsureStatus> EnsurePackage(string packageName, IConso
651
725
652
726
public static async Task < PackageEnsureStatus > EnsurePackage ( string packageName , string version , IConsole console )
653
727
{
654
- packageName = packageName . ToLower ( ) ;
728
+ if ( ! EnsureAdminCanExtract ( console ) )
729
+ {
730
+ return PackageEnsureStatus . Unknown ;
731
+ }
732
+
733
+ packageName = packageName . ToLower ( ) ;
655
734
656
735
if ( string . IsNullOrWhiteSpace ( packageName ) )
657
736
{
0 commit comments