Connection errors when using msrdcex prevent new connections.
Currently an error connecting to a session prevents additional connections.
Steps to reproduce.
- Create an AVD application/desktop with a target executable or host that does not exist.
- Use msrdcex to connect to that resource.
- Leave the error window open.
- Launch msrdcex again with a known working application.
Current behavior:
The second launch of msrdcex does not attempt to connect until the error box is closed on the first msrdcex instance.
Expected behavior
The second instance of msrdcex should launch instantly.
MSRDC does seem to be misbehaving when it has multiple processes like this, do you know if this is specific to MsRdpEx, or if it happens with "vanilla" MSRDC as well? If it's not MsRdpEx-specific, then it would mean the problem is in MSRDC, and we'd have to figure out a way to change the behavior with the API hooking
I was able to reproduce this with the vanilla MSRDC.
From PowerShell, you can use "Get-Process msrdc | Stop-Process" to get things back on track. I have often seen zombie msrdc.exe processes throughout a day of launching it several times for development. I don't know if there's really a way I can force it not to call into the existing msrdc process, and it doesn't seem to always do it, only at specific times like the case you've found.
The only problem with Get-Process msrdc | Stop-Process is that any currently open desktops or remoteapps to AVD are killed as well. It seems the error process is spawned as an additional sibling to the currently open sessions, and it then prevents more siblings from spawning.
I created a work around using FindWindow and sending WM_CLOSE to the Handel with the class TSC_CONNECTING_DIALOG_PARENT_WNDCLASS It's not ideal but it works.
The method below could be called with a flag on MSRDCX, but that feels a little hacky because the issue is with a process outside the scope of this project.
public static void CloseRdcErrorWindows()
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
const UInt32 WM_CLOSE = 0x0010;
void CloseWindow(IntPtr hwnd)
{
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
List<IntPtr> Windows = FindWindow.GetWindowHandles("msrdc", "TSC_CONNECTING_DIALOG_PARENT_WNDCLASS");
foreach (IntPtr Window in Windows)
{
try
{
CloseWindow(Window);
}
catch
{
}
}
}