Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Console output #702

Open
mcc85s opened this issue Sep 25, 2024 · 2 comments
Open

Console output #702

mcc85s opened this issue Sep 25, 2024 · 2 comments

Comments

@mcc85s
Copy link

mcc85s commented Sep 25, 2024

Greetings,

This is not an issue with Netradiant per se, however I'm curious to know how tools like (mbspc.exe/bspc.exe), qmap2.exe, etc. sends stuff to the console in your application, because I've been attempting to implement that into a WPF application I've been making that uses XAML and PowerShell that helps orchestrate the process of
compiling and packaging a map

I'm not trying to build something as complicated as Netradiant, however, I want to use PowerShell to wrap and log all of the things I'm doing to a particular map, or multiple. Being able to redirect the standard output or error output from these tools has crashed with virtually every (attempt/approach) I've made.

I even took some time to try out various other approaches that Microsoft Copilot suggested.

So like, if I run something like this:

$process = Start-Process -FilePath $Filepath -ArgumentList $ArgumentList -NoNewWindow -RedirectStandardOutput "output.txt" -RedirectStandardError "error.txt" -PassThru
$process.WaitForExit()

$output = Get-Content "output.txt"
$xerror = Get-Content "error.txt"

...that works, but the process has to complete before I can access or see any of that data.

But as soon as I try an approach like this...

$process = New-Object System.Diagnostics.Process
$process.StartInfo = New-Object System.Diagnostics.ProcessStartInfo
$process.StartInfo.FileName = $Filepath
$Process.StartInfo.Arguments = $ArgumentList
$process.StartInfo.RedirectStandardOutput = $true
$process.StartInfo.RedirectStandardError = $true
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.CreateNoWindow = $true

$process.EnableRaisingEvents = $true

$process.add_OutputDataReceived({
    param($sender, $args)
    if ($args.Data -ne $null) {
        Write-Host $args.Data
    }
})

$process.add_ErrorDataReceived({
    param($sender, $args)
    if ($args.Data -ne $null) {
        Write-Host "ERROR: " + $args.Data
    }
})

$process.Start()
$process.BeginOutputReadLine()
$process.BeginErrorReadLine()

$process.WaitForExit()

...the process does something, but it locks up my console host and doesn't return anything to the screen, so I have to terminate the console host.

But I can see very clearly if I build the map using Netradiant, it updates the information on the fly.

Perhaps you could offer some insight...?

@TTimo
Copy link
Owner

TTimo commented Sep 26, 2024

Hello,

This is GtkRadiant and not NetRadiant. I don't know what NetRadiant does, they could have a completely different implementation of this stuff.

But I can answer for GtkRadiant - the version of q3map2.exe that we use has an option to stream out it's output over a TCP connection back to the editor.

This was useful in contexts where compilations were still being done on a much larger, shared central server, and it also had the advantage of being portable. It also allowed the debug stream to flag bad brushes and highlight them during the BSP phase, that sort of thing.

Iirc for tools that do not support the TCP streaming we just execute a batch file and don't really look at the output, until after completion maybe.

This was all written long before PowerShell existed, so it uses none of that. Capturing stdout/stderr from Win32 console applications is a notorious quagmire.

I think if I had to do this nowadays I'd use python's subprocess module which I'm pretty sure can do it and provide a reasonably sane API. It'll also be portable without over-complicating things which is always a bonus.

Of course this would all just wrap around suitable CreateProcess usage and you could go directly to that and write a Windows only solution (https://learn.microsoft.com/en-us/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output). That requires a level of proficiency with Win32 APIs that I don't care for though.

@mcc85s
Copy link
Author

mcc85s commented Sep 26, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants