-
Notifications
You must be signed in to change notification settings - Fork 354
Delete ExternalTools directory on Npm Cache Clear #1053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f56f26d
6a54647
8226db9
138a3ad
1ebb190
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,25 +15,20 @@ | |
| //*********************************************************// | ||
|
|
||
| using System; | ||
| using System.Diagnostics; | ||
| using System.IO; | ||
| using System.Windows.Forms; | ||
| using Microsoft.NodejsTools.Project; | ||
| using Microsoft.VisualStudio.Shell; | ||
| using Microsoft.VisualStudioTools; | ||
|
|
||
| namespace Microsoft.NodejsTools.Options { | ||
| public partial class NodejsNpmOptionsControl : UserControl { | ||
|
|
||
| private string _npmCachePath; | ||
|
|
||
| public NodejsNpmOptionsControl() { | ||
| InitializeComponent(); | ||
| } | ||
|
|
||
|
|
||
| internal void SyncControlWithPageSettings(NodejsNpmOptionsPage page) { | ||
| _showOutputWhenRunningNpm.Checked = page.ShowOutputWindowWhenExecutingNpm; | ||
| _npmCachePath = page.NpmCachePath; | ||
| _cacheClearedSuccessfully.Visible = false; | ||
| } | ||
|
|
||
|
|
@@ -42,34 +37,57 @@ internal void SyncPageWithControlSettings(NodejsNpmOptionsPage page) { | |
| } | ||
|
|
||
| private void ClearCacheButton_Click(object sender, EventArgs e) { | ||
| bool didClearNpmCache = TryDeleteCacheDirectory(NodejsConstants.NpmCachePath); | ||
| bool didClearTools = TryDeleteCacheDirectory(NodejsConstants.ExternalToolsPath); | ||
|
|
||
| if (!didClearNpmCache || !didClearTools) { | ||
| MessageBox.Show( | ||
| SR.GetString(SR.CacheDirectoryClearFailedCaption, NodejsConstants.NtvsLocalAppData), | ||
| SR.GetString(SR.CacheDirectoryClearFailedTitle), | ||
| MessageBoxButtons.OK, | ||
| MessageBoxIcon.Information); | ||
| } | ||
|
|
||
| _cacheClearedSuccessfully.Visible = didClearNpmCache && didClearTools; | ||
| } | ||
|
|
||
| private static bool TryDeleteCacheDirectory(string cachePath) { | ||
| if (!Directory.Exists(cachePath)) { | ||
| return true; | ||
| } | ||
|
|
||
| try { | ||
| Directory.Delete(_npmCachePath, true); | ||
| _cacheClearedSuccessfully.Visible = true; | ||
| } catch (DirectoryNotFoundException) { | ||
| // Directory has already been deleted. Do nothing. | ||
| _cacheClearedSuccessfully.Visible = true; | ||
| } catch (IOException exception) { | ||
| // To handle long paths, nuke the directory contents with robocopy | ||
| string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); | ||
| Directory.CreateDirectory(tempDirectory); | ||
| var psi = new ProcessStartInfo("cmd.exe", string.Format(@"/C robocopy /mir ""{0}"" ""{1}""", tempDirectory, cachePath)) { | ||
| UseShellExecute = false, | ||
| CreateNoWindow = true | ||
| }; | ||
|
|
||
| using (var process = Process.Start(psi)) { | ||
| process.WaitForExit(10000); | ||
| } | ||
|
|
||
| // Then delete the directory itself | ||
| try { | ||
| Directory.Delete(cachePath, true); | ||
| } catch (DirectoryNotFoundException) { | ||
| // noop | ||
| } | ||
|
|
||
| return !Directory.Exists(cachePath); | ||
| } catch (IOException) { | ||
| // files are in use or path is too long | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh, just now realizing this case might be pretty likely in the case of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here was the script I used: C:\Users\matb.REDMOND\AppData\Local\Microsoft\Node.js Tools> Get-ChildItem -Recurse . | % { $_.fullname } | sort -Property LengthLongest path is 150 characters with Node 6 and my relatively short user name.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On < Node 6, the max path was 273 :sad: I changed the logic to use For reference, another way to delete long path files is with the Windows
|
||
| MessageBox.Show( | ||
| string.Format("Cannot clear npm cache. {0}", exception.Message), | ||
| "Cannot Clear npm Cache", | ||
| MessageBoxButtons.OK, | ||
| MessageBoxIcon.Information | ||
| ); | ||
| return false; | ||
| } catch (Exception exception) { | ||
| try { | ||
| ActivityLog.LogError(SR.ProductName, exception.ToString()); | ||
| } catch (InvalidOperationException) { | ||
| // Activity Log is unavailable. | ||
| } | ||
|
|
||
| MessageBox.Show( | ||
| string.Format("Cannot clear npm cache. Try manually deleting the directory: {0}", _npmCachePath), | ||
| "Cannot Clear npm Cache", | ||
| MessageBoxButtons.OK, | ||
| MessageBoxIcon.Information | ||
| ); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: nuke -> exterminate 🤖