--- name: windows-paths description: Handle Windows file paths correctly in code, shells, and configs. Use when creating files, resolving paths, fixing path errors, dealing with spaces, drive letters, UNC, long paths, path separators, MAX_PATH, case-insensitivity, or converting between Windows and POSIX/WSL paths. license: MIT metadata: author: javeckbila version: "1.0.0" platform: windows --- # Windows paths for coding agents ## Ground rules 1. **Windows paths are usually case-insensitive** (default NTFS). Do not rename `Util.cs` ↔ `util.cs` casually — git can break. 2. **Separator:** `\` is native; `/` often works in modern tools and .NET — still prefer `\` in PowerShell examples and raw Win32 contexts. 3. **Drive letters:** `C:\...` absolute. Relative paths are fine inside repos. 4. **Spaces are common** (`Program Files`, user profile names). Always quote. ## PowerShell path APIs (prefer these) ```powershell Join-Path $root 'src' 'lib' # PS 6+ multi child Join-Path $root (Join-Path 'src' 'lib') # PS 5.1 Split-Path $path -Parent Split-Path $path -Leaf Resolve-Path -LiteralPath $path # must exist [System.IO.Path]::GetFullPath($path) # normalize without requiring existence Test-Path -LiteralPath $path ``` Use **`-LiteralPath`** when the path may contain `[` `]` wildcards. ## Wrong vs right | Wrong | Right | |-------|-------| | `cd C:\Users\Ada Smith\proj` (unquoted spaces) | `Set-Location -LiteralPath 'C:\Users\Ada Smith\proj'` | | Hardcode `C:\Users\you\...` in shared code | Use `$env:USERPROFILE`, `$PSScriptRoot`, repo-relative paths | | `open('/home/user/proj/file')` on native Windows | Use Windows path or WSL intentionally | | Assume `~/` expands everywhere | `$env:USERPROFILE` or `$HOME` in PowerShell | | `rm C:\` style broad paths | Resolve + confirm before delete | | Create `con`, `nul`, `aux`, `prn` filenames | Avoid reserved device names | ## Reserved names and invalid characters - Reserved: `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, `LPT1`–`LPT9` (any extension still dangerous) - Invalid in names: `< > : " | ? *` and control chars - Do not end names with space or period ## Long paths (MAX_PATH) Classic limit ~260 characters. Symptoms: "path too long", silent tool failures. Mitigations: 1. Prefer shorter repo roots (`C:\src\app` not deep Desktop trees) when scaffolding 2. Enable long paths (user/machine policy) — do not force this without consent: ```powershell # Check (may need admin to enable) Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -ErrorAction SilentlyContinue ``` 3. Use `\\?\C:\very\long\path` only when an API documents support 4. In git: `git config --global core.longpaths true` (helpful on large monorepos) ## UNC and network paths ```text \\server\share\folder\file.txt ``` - `Set-Location \\server\share` can work; some tools need mapped drives - Do not convert UNC to `C:\` incorrectly ## Path conversion (WSL) ```powershell # Windows → WSL (from PowerShell with wsl present) wsl wslpath -a 'C:\Users\Ada\project' # WSL → Windows (inside WSL) wslpath -w '/home/ada/project' ``` Typical mapping: `C:\Users\Ada` ↔ `/mnt/c/Users/Ada` **Never mix** `C:\...` arguments into a Linux binary without conversion. ## In source code ### .NET / C# ```csharp var path = Path.Combine(root, "data", "file.txt"); var full = Path.GetFullPath(path); ``` ### Node.js ```js const path = require('path'); path.join(root, 'data', 'file.txt'); // OS-correct path.win32.join(...) // force Windows path.posix.join(...) // force POSIX ``` ### Python ```python from pathlib import Path p = Path.home() / "project" / "file.txt" p.resolve() ``` ### Cross-platform libraries Prefer `path.join` / `pathlib` / `Path.Combine` over string concatenation with `/` or `\`. ## Config files agents often break - **Docker / compose:** container paths are Linux even on Docker Desktop — keep container side POSIX; only host bind mounts use Windows paths (and `/` often works: `C:/Users/...`) - **GitHub Actions:** runners may be Windows — use correct `shell: pwsh` and paths - **VS Code / launch.json:** `${workspaceFolder}` over absolute user paths - **.env files:** quote values with backslashes carefully; prefer forward slashes if the app accepts them ## Checklist before writing a path - [ ] Exists or should be created? (`New-Item -Force`) - [ ] Quoted if spaces? - [ ] Repo-relative for shared projects? - [ ] Native Windows vs WSL vs container? - [ ] Under ~240 chars if long-path support unknown?