2

What's wrong with these PowerShell Commands. its doesn't write the file "test.txt"

PS> $stuff = @("AAA`n", "BBB`n")
PS> [System.IO.File]::WriteAllLines(".\test.txt", $stuff)
PS> dir
# Nothing here....

Is there anything misconfigured on my Computer that could cause this? Do I need to somehow reinstall .net?

mklement0
  • 382,024
  • 64
  • 607
  • 775
pico
  • 1,660
  • 4
  • 22
  • 52
  • .NET's working directory usually differs from PowerShell's, so you should always pass _full, file-system-native_ paths to .NET method calls. Use [`Convert-Path`](https://learn.microsoft.com/powershell/module/microsoft.powershell.management/convert-path) to convert a relative path to a full file-system-native one, assuming it already exists. To specify a file to be created in PowerShell's current location, use something like `"$PWD\file.txt"`, except from PS-specific drives. For more information, see [this answer](https://stackoverflow.com/a/57791227/45375) to the linked duplicate. – mklement0 Oct 23 '21 at 14:50

2 Answers2

1

Try dir ~\test.txt - or use an absolute path c:\path\to\my\test.txt. Better yet look at the Set-Content cmdlet.

FYI: theres nothing wrong with your computer - your using a dotnet library so you need to be more specific (basically). Set-Content is the powershell way of doing this (and .\test.txt would work as your were expecting).

MisterSmith
  • 2,884
  • 1
  • 10
  • 13
1

.Net doesn't use the same path as your PowerShell. The solution is to resolve a relative path into a fullpath:

PS C:\> $stuff = @("AA", "BB")
PS C:\> $out_file = ".\out.txt"
PS C:\> New-Item -Force -Path $out_file
PS C:\> $out_full = $(Resolve-Path -Path $out_file)
PS C:\>[System.IO.File]::WriteAllLines(` 
    ".\testing.txt", $out_full)

A better way:

function open_w {
    param([string]$path)
    write-host "path: $path"
    $pathfix =  $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path)
    return [System.IO.StreamWriter]::new($pathfix)
}
pico
  • 1,660
  • 4
  • 22
  • 52
  • 1
    You have the parameters wrong.. Should be `[System.IO.File]::WriteAllLines($out_full, $stuff)`. Also you don't need to create that file first with `New-Item` because [WriteAllLines()](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.writealllines?view=net-5.0#System_IO_File_WriteAllLines_System_String_System_String___) _"Creates a new file, writes the specified string array to the file, and then closes the file."_. Finally, you also don't need the `@()` for creating the `$stuff` array. Just the commas in between the values will do. – Theo Oct 23 '21 at 10:01
  • 1
    It is commendable that you want to alert others to this classic pitfall (the current directories differing between PowerShell and .NET), but the sample code is problematic. In addition to what @Theo has already stated: `$out_full = "$pwd\out.txt"` will do in most cases; for full robustness: `"$((Get-Location -PSProvider FileSystem).ProviderPath)\out.txt"`. If you do need to resolve, don't use `Resolve-Path`: it won't resolve a _PS-specific_-drive-based path to a _file-system-native_ one, the latter being what .NET APIs require; use `Convert-Path` instead. No need for `$(...)` on the RHS of `=` – mklement0 Oct 23 '21 at 14:44
  • the short version is `[System.IO.File]::WriteAllLines($pwd.Path+'\file.txt', $lines);` – Stadub Dima Feb 28 '23 at 07:17