0
  • I'm using Kalles' Fraktaler on Windows 10 to render images of the Mandelbrot set. Bundled with KF is a program to take a single parameter file and beak it into multiple tiles for easier rendering.

  • The output for the tiling program is multiple files with the following naming scheme: name-0000-0000.kfr, name-0000-0000.kfs, where the name can be anything and the numbers increment as needed.

    • The .kfr files are the parameter files.
    • The .kfs files are the settings files.

After I have these generated parameter and setting files, I can execute KF on the command line with the following arguments:

kf.exe -s name-0000-0000.kfs -l name-0000-0000.kfr -p name-0000-0000.png

Doing this for every pair of parameter and setting files works perfectly fine, taking the input files and saving the render to name-0000-0000.png

I asked the developer for an example PowerShell script to automate the process for when there are dozens or more of the files that need to be rendered, and this is what he gave me. The script needs to be run from the same directory as the files are stored.

Get-ChildItem "." -Filter *.kfr |
Foreach-Object {
  $kfr = $_.FullName
  $kfs = $kfr.replace("kfr", "kfs")
  $png = $kfr.replace("kfr", "png")
  C:/path/to/kf.exe -s $kfs -l $kfr -p $png
}

Unfortunately, I've tried every variation of this script that I could think of, and nothing gives me any results. I have already allowed unsigned scripts to be run on my computer. I would greatly appreciate some help on this.

Dai
  • 141,631
  • 28
  • 261
  • 374

1 Answers1

0

(PowerShell is nice and flexible - but only when you use it to invoke only PowerShell commands rather than running native executables. For example, to run a program in the current directory you need to prefix the program's name with ./ - ostensibly this is done for safety and I assume for similarity to Unix shells, but it's the first in a long list of gotchas for anyone wanting to use PowerShell for tasks that would be trivial in old-school batch files)

Anyway, you need to use Invoke-Command or Start-Process.

I've changed your script from using a piped expression into an easier-to-digest loop (and invoking .NET's Path.ChangeExtension directly because PowerShell's built-in string match-and-replace syntax is too arcane for me):

$kfrFiles = Get-ChildItem "." -Filter "*.kfr"
foreach ( $kfrFile in $kfrFiles ) {
    
    $kfr = $kfrFile.Name
    $kfs = [System.IO.Path]::ChangeExtension( $kfrFile.Name, "kfs" )
    $png = [System.IO.Path]::ChangeExtension( $kfrFile.Name, "png" )

    Start-Process -FilePath "C:\path\to\kfs.exe" -ArgumentList "-s $kfs", "-l $kf", "-p $png" -Wait
}

The -Wait option will wait for the kfs.exe program to finish before starting the next instance - otherwise if you have hundreds of .kfr files then you'll end-up with hundreds of kfr processes running concurrently.

I don't know how to allow concurrent processes but impose a limit on the maximum-number of concurrent processes in PowerShell. It is possible, just complicated.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • Okay, thank you very much. This seems to work perfectly. You just saved me from another few weeks of ripping my hair out trying to find a solution. – Chronicler1701 Jul 08 '20 at 03:44