Skip to content

Troubleshooting

Rod Christiansen edited this page Sep 3, 2026 · 1 revision

Troubleshooting

Most csharpDialog failures are silent. Unknown flags are ignored, unknown command-file verbs are ignored, an unmatched list-item title is ignored, and several parsed flags do nothing at all. Start from the two logs, then work down this table.

Where to look first

The dialog's own log

%ProgramData%\ManagedNotifications\logs\csharpdialog.log

One line per entry, [yyyy-MM-dd HH:mm:ss] LEVEL message, level padded to five characters. It records process start with the full argument list, warnings, errors and the exit code — enough to answer "did it run, with what arguments, and how did it end". It does not record every command-file command.

The file rolls at 5 MB keeping five generations; csharpdialog.log.1 is the newest rotated one. There is no verbosity switch: the level set is fixed.

Get-Content "$env:ProgramData\ManagedNotifications\logs\csharpdialog.log" -Tail 40

If a build older than the current one ran on this machine, its log lived under %ProgramData%\ManagedUtilities\logs\. The first write of a current build moves that file and its generations across, so history is preserved; an empty new log plus a populated old one means the move has not run yet, not that logging is broken.

Standard output

dialog.exe is verbose on stdout: [DEBUG] lines from the WPF path and [CommandFileMonitor] lines from the watcher, including every line it read and whether it parsed. That stream is the best place to see whether a command file line was seen and understood.

& dialog --window --commandfile C:\temp\cmd.txt --title Test *> C:\temp\dialog-stdout.txt

Because of this noise, scripts must parse for the Result: prefix rather than treating stdout as clean.

Symptom → cause → fix

It printed a text menu instead of opening a window

Cause. No front-end flag was given. dialog.exe only uses the WPF window when it sees --window, --fullscreen, --kiosk, --firstrun, --autolaunch or --commandfile. Everything else falls back to the console front end, which prints the dialog and blocks on Console.ReadLine().

Fix. Add --window. This is the single most common transliteration error from swiftDialog.

The script hangs forever with no window

Cause. Same as above, in a non-interactive context: the console front end is waiting on stdin that will never arrive.

Fix. Add --window. As a safety net, give every unattended dialog a --timeout.

The dialog never appears

Work through these in order.

Check How
Did the process start at all? Look for a starting: line in the log with your arguments
Did it exit immediately? An Exiting with code 0 right after start with --autolaunch means first-run detection said no. That is by design
Which session did it run in? Get-Process dialog | Select-Object Id, SessionId. Session 0 is invisible to users

Session 0 is the usual answer. A dialog started by a Windows service, or by a scheduled task set to run as SYSTEM, draws on the session 0 desktop where no interactive user can see it. csharpDialog contains no session-shifting code — no CreateProcessAsUser, no WTS session enumeration — so it cannot put itself in front of the user.

Fix. Run it in the user's session: a logon scheduled task with an interactive principal, an HKCU/HKLM Run entry, or a logon script. See Recipes.

Command-file commands do nothing

Cause Check Fix
The verb is one the window ignores Compare against the accepted-but-ignored list Do the work in the script and report it with title:/message:/progress:/listitem:
The verb is misspelled stdout shows the line "did not parse to a command" Fix the spelling; the parser silently drops unknown verbs
Commands were written before the watcher started — Sleep ~2 s after launching before the first append
The file was rewritten instead of appended The monitor reads forward from a stored byte offset; a truncated file produces no reads until it grows past the old offset Only ever append. Delete the file before launching, never during
No BOM-free UTF-8 Garbled first line Use Add-Content -Encoding UTF8

A listitem: update does nothing

Cause. Rows are keyed by exact title. A mismatch in case, spacing, or trailing punctuation finds no row and silently does nothing. A duplicate title makes the earlier row permanently unreachable.

Fix. Store the titles in a variable and use the same variable for the add and every update. If titles cannot be unique, update by index instead. Titles containing commas cannot work at all — the parameter splitter breaks on every comma.

listitem: delete and list: clear do nothing

Cause. Neither is implemented. delete parses and falls through to the update branch; list has no window handler at all.

Fix. Do not remove rows. Add every row up front and change its status instead — which is also better UI, because the user can see the full scope from the start.

The progress bar does not move / starts in the wrong place

Cause. dialog.exe does not apply the launch-time progress value or caption. The bar starts where its XAML left it and only moves in response to progress: commands. And --progress-max is inert: the maximum is fixed at 100.

Fix. Use --progress with no value just to make the bar visible, then send progress: 0 as the first command-file line, and treat every subsequent value as a percentage.

--icon, --image, --backgroundcolor, --fontfamily and friends have no effect

Cause. Not a bug you can configure around: dialog.exe uses a fixed-layout window that only assigns the properties it explicitly reaches for. These flags are parsed into the configuration and never read. They are honoured only by the separate csharpDialog.WPF.exe host, which has no list, no progress bar and no command file.

Fix. None for the styling flags. For per-row icons, pass an existing absolute file path in the third field of --listitem.

--topmost does not keep the window in front

Cause. Inert in dialog.exe; the window's topmost state comes from its XAML.

Fix. Use --fullscreen, whose overlay is always topmost.

The user closed a window that was supposed to be locked

Cause. --button1disabled alone leaves Esc, Enter and Alt+F4 live.

Fix. Combine all three: --button1disabled --hidedefaultkeyboardaction --quitkey 0. Use --kiosk when it must also be undismissable and cover the screen. Remember kiosk mode cancels every close, so the controlling script must always have a path that writes quit, including its error path.

A kiosk dialog is stuck on screen

Cause. The controlling script died before writing quit, and kiosk mode cancels close attempts.

Fix. Write quit into the command file from another shell, or end the process:

Add-Content "C:\ProgramData\ManagedNotifications\work\deploy.txt" "quit" -Encoding UTF8
Stop-Process -Name dialog -Force

Prevent. Always pass a --timeout on kiosk dialogs, and wrap the script body in try/finally with the quit in the finally.

The fullscreen backdrop is a flat grey instead of blurred

Cause. The acrylic system-backdrop attribute needs Windows 11 22H2 or later. On older builds the DWM call fails silently.

Fix. None needed — the dimmed overlay still works. This is cosmetic.

--cimian shows an empty list, or rows that never move

Cause Check
Monitoring never started — not a first-run scenario, no log found, or no client process The log carries the specific reason; stdout carries "Could not start Cimian monitoring"
No manifests cached, so the placeholder three-item list appeared Get-ChildItem "$env:ProgramData\ManagedInstalls\manifests\*.yaml"
The client's log wording no longer matches the monitor's patterns Get-Content "$env:ProgramData\ManagedInstalls\reports\run.log" -Tail 40 -Wait and compare against the recognised patterns

Fix. For anything you need to be reliable, drive the list from your own script instead of --cimian. The pattern is in Cimian Integration.

The exit code is 1 and I expected 2

Cause. csharpDialog only ever returns 0 or 1. There is no exit code 2, and no second button is rendered to produce one.

Fix. Distinguish outcomes from the Result: line on stdout (ok, button1, timeout, quit), or restructure so a single button plus a timeout is enough.

Windows SmartScreen or an application-control policy blocks it

Cause. GitHub release artifacts are unsigned; the public workflow has no certificate.

Fix. Sign the binaries with your organisation's certificate before deployment. The recipe is in Installation.

dialog is not recognised as a command

Cause. The installer appends to the machine PATH; a shell that was already open, or a scheduled task registered earlier, still has the old environment.

Fix. Open a new shell, or call the full path C:\Program Files\csharpDialog\dialog.exe. Services and tasks should always use the full path.

Collecting diagnostics for an issue report

$out = "$env:TEMP\csharpdialog-diag"
New-Item -ItemType Directory -Path $out -Force | Out-Null
Copy-Item "$env:ProgramData\ManagedNotifications\logs\csharpdialog.log*" $out -ErrorAction SilentlyContinue
Get-ItemProperty "HKLM:\Software\csharpDialog" | Out-File "$out\install.txt"
(Get-Item "C:\Program Files\csharpDialog\dialog.exe").VersionInfo | Out-File "$out\version.txt"

Include the exact command line, the command-file contents, and the captured stdout. Redact anything site-specific before attaching it to a public issue.

Clone this wiki locally