Lauch .RDP from a C# App while keeping taskbar hidden

M

Matthew Arkin

First: I'm not the best developer so please excuse any noobiness.

I have a friend that a CS teacher and he want to let his students use an
IDE during their exam. To minimize cheating I recommened that he set up
a server with RemoteApp and install the IDE (Greenfoot). Then I was able
to make a little app that will launch it.

I want the app to be on top of the taskbar but I can't do that unless I
set TopMost to true, but then they can't view the RDP session and if I
kill explorer then RDP won't connect.

So the real question is a) can I have an application sit on top of the
taskbar with out killing explorer and using TopMost? B) is there a way
to embed RDP into the app (I can use WPF or WinForm) or C) any other
suggestions?


Thanks!

Matthew Arkin
Windows Desktop Experience MVP
 
J

Jackie

First: I'm not the best developer so please excuse any noobiness.

I have a friend that a CS teacher and he want to let his students use an
IDE during their exam. To minimize cheating I recommened that he set up
a server with RemoteApp and install the IDE (Greenfoot). Then I was able
to make a little app that will launch it.

I want the app to be on top of the taskbar but I can't do that unless I
set TopMost to true, but then they can't view the RDP session and if I
kill explorer then RDP won't connect.

So the real question is a) can I have an application sit on top of the
taskbar with out killing explorer and using TopMost? B) is there a way
to embed RDP into the app (I can use WPF or WinForm) or C) any other
suggestions?


Thanks!

Matthew Arkin
Windows Desktop Experience MVP

It appears like you would be willing to terminate the shell process if
it allowed RDP to work properly. Taking that into consideration, how
about simply hiding the taskbar?
 
J

Jackie

It appears like you would be willing to terminate the shell process if
it allowed RDP to work properly. Taking that into consideration, how
about simply hiding the taskbar?

I don't currently have a chance to test anything in C# but at at least
the following WinAPIs can be used:
GetDesktopWindow
FindWindowEx - "Shell_TrayWnd" class
ShowWindow - hide/show

If I recall correctly, it may show itself again some time. Using this
method, you would need to make sure to hide it again. It would look a
little amateurish having it show up and then disappear again, so there
may be better ways.
You can also of course disable or hide the desktop using this method as
well.
 
M

Matthew Arkin

I don't currently have a chance to test anything in C# but at at least
the following WinAPIs can be used:
GetDesktopWindow
FindWindowEx - "Shell_TrayWnd" class
ShowWindow - hide/show

If I recall correctly, it may show itself again some time. Using this
method, you would need to make sure to hide it again. It would look a
little amateurish having it show up and then disappear again, so there
may be better ways.
You can also of course disable or hide the desktop using this method as
well.
Thanks, Would it be possible to just make the remote desktop window
topmost? (It also launches a seperate credentials window)? If so, would
that be easier?
 
J

Jackie

Thanks, Would it be possible to just make the remote desktop window
topmost? (It also launches a seperate credentials window)? If so, would
that be easier?

It does not appear to be a way to do this with only managed code. I am
thinking about something like this...
EnumWindows - enumerates all top-level windows
GetWindowThreadProcessId - get the ID of the process thread that created
the window
OpenProcess and GetModuleFileNameEx - get the file name of the process
and check if it's RDP

By now, you know that this window is owned by RDP at least and you can
do some additional checks, maybe.

After finding the right window(s)...
SetWindowPos - HWND_TOPMOST

Phew..

PInvoke is a good site to see how to use each API into C#:
http://www.pinvoke.net/
 
J

Jackie

I wrote an example application, however, entirely in C/C++.
It follows pretty much the same instructions as I mentioned earlier.

It finds all top-level windows associated with the process mstsc.exe (if
that's the one you want) and just prints some info into a console window.

--------------------
Windows associated with RD:
'Remote Desktop Connection' (0x00410AF4)
'Remote Desktop Connection' (0x000A0C56)
'' (0x001E0BDA)
'' (0x000A0D34)
'' (0x00090BE0)
'' (0x00200916)
'MSCTFIME UI' (0x00240C0A)
'Default IME' (0x00150BFE)
--------------------

I didn't try anything more than opening mstsc without doing anything. At
least the window where you can connect stays on top of all other
non-topmost windows.
I wrote the code in C++ because it was quicker for me without converting
any APIs to C# code. I can give you the code. Just use the site I gave
you earlier (PInvoke) to check how to use the APIs in C# (mostly
copy/paste).
 
M

Matthew Arkin

I wrote an example application, however, entirely in C/C++.
It follows pretty much the same instructions as I mentioned earlier.

It finds all top-level windows associated with the process mstsc.exe (if
that's the one you want) and just prints some info into a console window.

--------------------
Windows associated with RD:
'Remote Desktop Connection' (0x00410AF4)
'Remote Desktop Connection' (0x000A0C56)
'' (0x001E0BDA)
'' (0x000A0D34)
'' (0x00090BE0)
'' (0x00200916)
'MSCTFIME UI' (0x00240C0A)
'Default IME' (0x00150BFE)
--------------------

I didn't try anything more than opening mstsc without doing anything. At
least the window where you can connect stays on top of all other
non-topmost windows.
I wrote the code in C++ because it was quicker for me without converting
any APIs to C# code. I can give you the code. Just use the site I gave
you earlier (PInvoke) to check how to use the APIs in C# (mostly
copy/paste).

Thanks for all your help, I'll see if I can get it to work.
 
J

Jackie

Thanks for all your help, I'll see if I can get it to work.

In case you would like to see my C/C++ code for reference, I put it up here:
http://pastebin.com/rFi4UrQ3

I used QueryFullProcessImageName instead of GetModuleFileNameEx to not
depend on psapi.dll.

Should hopefully be easy to convert it to C# with some help from
PInvoke. Good luck! :)
 
M

Matthew Arkin

In case you would like to see my C/C++ code for reference, I put it up
here:
http://pastebin.com/rFi4UrQ3

I used QueryFullProcessImageName instead of GetModuleFileNameEx to not
depend on psapi.dll.

Should hopefully be easy to convert it to C# with some help from
PInvoke. Good luck! :)

Hi Jackie,
I found this class at
http://www.codeproject.com/KB/miscctrl/hide_vista_start_orb.aspx
Which allowed me to just hide the taskbar, and with RemoteApp even if
the user clicked my app window, if they click the button that loads the
RDP, all their work is still their. Now I just need to add some code to
block any bad keystrokes and that should be it.

Thanks for all your time and help.

Matt
Windows Desktop Experience MVP
 
J

Jackie

Hi Jackie,
I found this class at
http://www.codeproject.com/KB/miscctrl/hide_vista_start_orb.aspx
Which allowed me to just hide the taskbar, and with RemoteApp even if
the user clicked my app window, if they click the button that loads the
RDP, all their work is still their. Now I just need to add some code to
block any bad keystrokes and that should be it.

Thanks for all your time and help.

Matt
Windows Desktop Experience MVP

Oh I see. I am glad that works well for you. Good luck! :)
 
D

David Ching

Matthew Arkin said:
B) is there a way to embed RDP into the app (I can use WPF or WinForm)

Just today I stumbled onto the Microsoft RDP Client Control that appears in
the Choose Toolbox Items dialog in the COM Components tab of Visual Studio,
so it does seem there is already an ActiveX control for you to be able to
put into your app. Search "microsoft rdp client control" or "Remote Desktop
ActiveX Control" for more info.

-- David
 
J

Jeff Johnson

Matthew Arkin
Windows Desktop Experience MVP

May I recommend that you don't cross-post between the MS public and private
groups? Not that it's going to matter for much longer, but, you know....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top