{"record":{"id":"37e2417789e11223","repo":"memstechtips/Winhance","slug":"could-not-delete-the-existing-working-directory","errorCode":null,"errorMessage":"Could not delete the existing working directory '{workingDirectory}'. It may be open in Windows Explorer or being used by another process. Please close it or delete it manually and try again.","messagePattern":"Could not delete the existing working directory '(.+?)'\\. It may be open in Windows Explorer or being used by another process\\. Please close it or delete it manually and try again\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Winhance.Infrastructure/Features/AdvancedTools/Services/IsoService.cs","lineNumber":115,"sourceCode":"                _logService.LogInformation($\"Clearing existing working directory: {workingDirectory}\");\r\n\r\n                try\r\n                {\r\n                    var script = $@\"\r\n                        Get-ChildItem -Path '{workingDirectory}' -Recurse -Force | ForEach-Object {{ $_.Attributes = 'Normal' }}\r\n                        Remove-Item -Path '{workingDirectory}' -Recurse -Force -ErrorAction Stop\r\n                    \";\r\n\r\n                    var removeResult = await _processExecutor.ExecuteAsync(\r\n                        \"powershell.exe\",\r\n                        $\"-NoProfile -ExecutionPolicy Bypass -Command \\\"{script}\\\"\",\r\n                        cancellationToken).ConfigureAwait(false);\r\n                    var errorOutput = removeResult.StandardError;\r\n\r\n                    if (_fileSystemService.DirectoryExists(workingDirectory))\r\n                    {\r\n                        _logService.LogError($\"Failed to delete working directory. It may be in use by another process: {errorOutput}\");\r\n                        throw new InvalidOperationException(\r\n                            $\"Could not delete the existing working directory '{workingDirectory}'. \" +\r\n                            \"It may be open in Windows Explorer or being used by another process. \" +\r\n                            \"Please close it or delete it manually and try again.\"\r\n                        );\r\n                    }\r\n\r\n                    _logService.LogInformation(\"Working directory cleared successfully\");\r\n                }\r\n                catch (OperationCanceledException)\r\n                {\r\n                    throw;\r\n                }\r\n                catch (InvalidOperationException)\r\n                {\r\n                    throw;\r\n                }\r\n                catch (Exception cleanupEx)\r\n                {\r","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/memstechtips/Winhance/blob/f23d554eb2d6400b1827bcc46b91294ffa53fbc9/src/Winhance.Infrastructure/Features/AdvancedTools/Services/IsoService.cs#L97-L133","documentation":"Thrown by IsoService after a PowerShell Remove-Item -Recurse -Force call failed to actually remove the ISO working directory — the post-deletion DirectoryExists check still returns true. This is not a normal cleanup failure: Remove-Item ran with -ErrorAction Stop but the directory survived, so the code treats the working directory as locked and refuses to proceed with ISO creation over a stale tree.","triggerScenarios":"Calling the ISO-mount/create flow when a previous working directory already exists and cannot be removed. The directory is open in Windows Explorer, a file handle is held by another process (antivirus, search indexer, a mounted child ISO, or the previous oscdimg run still finishing), or the path requires elevation the current process does not have.","commonSituations":"A prior ISO creation run crashed or was cancelled, leaving a partial working directory. Antivirus (Windows Defender real-time scan) or the Explorer preview pane holds a handle to a file inside the directory. The directory sits on a network/UNC path or a drive the user lacks delete rights on. A file in the tree is read-only and -Force could not override a sharing violation.","solutions":["Close Windows Explorer windows showing the working directory and any apps that opened files inside it, then retry the operation.","Manually delete the working directory (%temp% or the configured ISO staging path) via Explorer or an elevated `rmdir /s /q \"<path>\"`, then retry.","Temporarily disable real-time antivirus scanning on the staging folder, or add it as an exclusion, to prevent handle contention during recursive delete.","Ensure the Winhance process is elevated (run as administrator) so it has delete rights on the full tree.","Check the logged StandardError output from Remove-Item (logged just before the throw) for the exact Win32 reason — it names the offending file and error code."],"exampleFix":"// before: single PowerShell Remove-Item; any sharing violation aborts the whole operation\nvar script = $\"Remove-Item -Path '{workingDirectory}' -Recurse -Force -ErrorAction Stop\";\n\n// after: retry loop with backoff, then fall back to renaming the stuck directory aside\nfor (int attempt = 0; attempt < 3; attempt++)\n{\n    if (!_fileSystemService.DirectoryExists(workingDirectory)) break;\n    await _processExecutor.ExecuteAsync(\"powershell.exe\",\n        $\"-NoProfile -ExecutionPolicy Bypass -Command \\\"Remove-Item -Path '{workingDirectory}' -Recurse -Force -ErrorAction Stop\\\"\",\n        cancellationToken).ConfigureAwait(false);\n    if (!_fileSystemService.DirectoryExists(workingDirectory)) break;\n    await Task.Delay(500 * (attempt + 1), cancellationToken).ConfigureAwait(false);\n}\nif (_fileSystemService.DirectoryExists(workingDirectory))\n{\n    var sideload = workingDirectory + $\".stuck.{DateTime.UtcNow:yyyyMMddHHmmss}\";\n    _fileSystemService.MoveDirectory(workingDirectory, sideload); // rename aside, continue\n    _logService.LogWarning($\"Could not delete working dir; moved aside to {sideload}\");\n}","handlingStrategy":"retry","validationCode":"// Before starting ISO creation, probe whether the staging dir is removable.\nbool CanClearWorkingDirectory(string dir) =>\n    !_fileSystemService.DirectoryExists(dir) || HasExclusiveDeleteAccess(dir);\n\nbool HasExclusiveDeleteAccess(string dir)\n{\n    try\n    {\n        foreach (var f in System.IO.Directory.EnumerateFiles(dir, \"*\", System.IO.SearchOption.AllDirectories))\n            using (var fs = new System.IO.FileStream(f, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None)) { }\n        return true;\n    }\n    catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"catch (InvalidOperationException ex) when (ex.Message.Contains(\"Could not delete the existing working directory\"))\n{\n    // surfaced to the user with the staging path and a 'close Explorer / delete manually' prompt;\n    // offer a retry once the user confirms they freed the handle.\n}","preventionTips":["Run the staging directory under %temp% on a local drive the process fully owns.","Add the staging folder to antivirus exclusions to prevent scan-handle contention during recursive delete.","Close Explorer windows that preview the staging tree before triggering a re-run.","On startup, proactively clean any leftover staging dir from a prior crashed run."],"tags":["filesystem","windows","io","cleanup","process-lock"],"backgroundTag":null,"analyzedSha":"f23d554eb2d6400b1827bcc46b91294ffa53fbc9","analyzedAt":"2026-08-13T17:55:20.922Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}