Skip to content

Commit d616e44

Browse files
authored
Bugfix: Uninstall-PSResource should delete subdirectories without Access Denied error on OneDrive (#1860)
1 parent eb00082 commit d616e44

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

src/code/Utils.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,16 @@ public static void DeleteDirectoryWithRestore(string dirPath)
16581658
}
16591659
}
16601660

1661+
private static void SetAttributesHelper(DirectoryInfo directory)
1662+
{
1663+
foreach (var subDirectory in directory.GetDirectories())
1664+
{
1665+
subDirectory.Attributes = FileAttributes.Normal;
1666+
SetAttributesHelper(subDirectory);
1667+
}
1668+
1669+
directory.Attributes = FileAttributes.Normal;
1670+
}
16611671
/// <Summary>
16621672
/// Deletes a directory and its contents
16631673
/// This is a workaround for .NET Directory.Delete(), which can fail with WindowsPowerShell
@@ -1672,21 +1682,25 @@ public static void DeleteDirectory(string dirPath)
16721682
}
16731683

16741684
// Remove read only file attributes first
1675-
foreach (var dirFilePath in Directory.GetFiles(dirPath,"*",SearchOption.AllDirectories))
1685+
foreach (var dirFilePath in Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories))
16761686
{
16771687
if (File.GetAttributes(dirFilePath).HasFlag(FileAttributes.ReadOnly))
16781688
{
16791689
File.SetAttributes(dirFilePath, File.GetAttributes(dirFilePath) & ~FileAttributes.ReadOnly);
16801690
}
16811691
}
1692+
1693+
DirectoryInfo rootDir = new DirectoryInfo(dirPath);
1694+
SetAttributesHelper(rootDir);
1695+
16821696
// Delete directory recursive, try multiple times before throwing ( #1662 )
16831697
int maxAttempts = 5;
16841698
int msDelay = 5;
16851699
for (int attempt = 1; attempt <= maxAttempts; ++attempt)
16861700
{
16871701
try
16881702
{
1689-
Directory.Delete(dirPath,true);
1703+
Directory.Delete(dirPath, true);
16901704
return;
16911705
}
16921706
catch (Exception ex)
@@ -1695,6 +1709,17 @@ public static void DeleteDirectory(string dirPath)
16951709
{
16961710
Thread.Sleep(msDelay);
16971711
}
1712+
else if (ex is System.IO.IOException)
1713+
{
1714+
string psVersion = System.Management.Automation.Runspaces.Runspace.DefaultRunspace.Version.ToString();
1715+
if (ex.Message.Contains("The directory is not empty") && psVersion.StartsWith("5"))
1716+
{
1717+
// there is a known bug with WindowsPowerShell and OneDrive based module paths, where .NET Directory.Delete() will throw a 'The directory is not empty.' error.
1718+
throw new Exception(string.Format("Cannot uninstall module with OneDrive based path on Windows PowerShell due to .NET issue. Try installing and uninstalling using PowerShell 7+ if using OneDrive."), ex);
1719+
}
1720+
1721+
throw new Exception(string.Format("Access denied to path while deleting path {0}", dirPath), ex);
1722+
}
16981723
else
16991724
{
17001725
throw;

0 commit comments

Comments
 (0)