Sunday, December 30, 2007

In a previous post I covered several issues I ran into with the vista rdp client. I have a few more problems that have pushed me to write my own RDP client. Its more a wrapper around the ActiveX control so it will require RDP 6.0 (and .NET 2.0) to be installed. But it does solve my problems.

I have every feature working except the single sign on. I am going to bounce that feature to a later release, but I do have a solution worked out for it.

My app can read any RDP file. I only implement a subset of the options, but I can use my existing RDP files. I did implement all the settings that we change. I also added a few new ones that control the new features I added. "disable close button:i:1" and "disable close button message:s:" are 2 examples of added settings.

To disable the close button, I just catch the close event and display a customizable message if the connection is still active. The return them to the form. This solves the issue we have with open record locks on disconnected sessions from people clicking the X to close.

The custom wrapper has the ability to read a password from the rdp file and use it in the connection. This allows me to publish shortcuts with generic usernames and passwords in them again.

I use RDX extensions to indicate encrypted files. I use TripleDES to protect the files from user changes. I have places that I don't want people messing with the settings. Also good for when the password is saved in the file. A custom RDX file editor is provided to my technicians that would need to make changes to the files.

And by default, the Windows key does not stick. That was a nice side effect.On deployment, I associate RDP and RDX run commands with my custom application. The icon is unchanged and my user experience does not change much.

Saturday, December 29, 2007

I just saw this post on Nicola Delfino's blog. I run into this same thing that he provides the solution for.

Update WinForm interface from a different threadWell, this is a typical issue when you have a thread that works (i.e. a Workflow) and a UI that needs to be updated.Let assume that you have a WinFom and you need to update its windows Title from another thread. The other thread needs to call "UpdateTitle" public method of current Form instance.In order to obtain that it works you need to implement "UpdateTitle".

Friday, December 28, 2007

The change to the new Vista RDP client can be a drastic one. A lot of things have changed. Several changes break existing functionality that many people relied on.

Windows key sticking:

If you use the windows key + L to lock your machine while working in a remote session, the windows key becomes stuck. When you return to your session, pressing any key that has a combination with the windows key will activate. E for explorer, L for lock, ect... The solution is to use ctrl +alt +del, or move focus away from the RDP session before locking the computer.

Default domain is wrong:

At some point all of our mstsc client forgot what domain they were connected to. Even though my users logged into the local machine with the domain account and tried to remote into a domain terminal server. They tried to authenticate with the machine name as the domain. The solution is to add the domain to the username when typing it in.

Passwords don't save to the rdp file anymore:

You cannot distribute a RDP file with a password. So the user must know the password to use the rdp shortcut.

Login prompt changed:

Not only is it client side, it also has a different look. You can revert it back by adding a special line into the .RDP file: enablecredsspsupport:i:0

Can only save one username/password per server:

This prevents you from creating 2 shortcuts with 2 different usernames to the same server. I read that you can add a second rdp listening port and point one of those to the new port number to work around this one.

At face value, these look like minor issues.

But the amount of support calls and issues this created in our environment tied us up for a long time. All of them user related. Technology is great when its transparent to the users (and does not generate calls to support staff).

We have a good number of users that cant figure out the difference between username passwords and email passwords. (I cant tell you the number of times we have had someone reboot to fix a problem only to have them call back to tell us they cant get the password to work anymore. ) The change that no longer defaults the domain, the change that sticks the windows key, and the different look of the login screen were all drastic changes to them.

We also have a special application that we deploy using RDP. We create a unique account for each computer that connects to it. We would save the password to the RDP so every user uses the same RDP on that machine. Now we have to have every possible user login, then give us the keyboard to enter the password. Not only is that a huge support drain, its an annoyance to our users. (especially to our remote sites that we visit once every other week).

At one point we added a second app to the servers and tried to create a second shortcut for that. Because the hostname was the same, it was only keeping the login details of one username. (we used a different username to access a different published app.)

The sticking window key compounds the problems. Our users don't know the password to that special application RDP connection. So when they get the windows key stuck and press the L key, the remote session gets locked. We get the call and have to remote into that session and enter the password for them.

Our primary solution that works wonders was to upgrade the Vista 6.0 version to the XP 5.2 version. That upgrade fixed all of those problems.

A second solution that I am about done with is to write my own client wrapper for the RDP 6.0 control. We have other issues that I can't solve any other way, and it solves these issues too. I will write up more details on that solution later.

Wednesday, December 26, 2007

I used to have an issue where my clipboard would stop working. I would eventualy have to reboot my computer to fix it. I would work with remote desktop alot and the mstsc was the cause of my problems. That write up explains exactly how the clipboard would lock up.

I uncovered a program that would show me the process containing the lock and allow you to kill it. I would love to link that program, but I cant track it down. I did find another one that a microsoft MVP posted that I think does the same thing. Here is a copy of that post.

Hassan,

This has to do with some application that's having a lock over the Windows Clipboard. David Candy's application should determine the Process that's causing the problem. Download GetOpenClipboardWindow.zip from here: http://windowsxp.mvps.org/temp/GetOpenClipboardWindow.zip Unzip and run the tool. Post back what it reports. For best results, run this utility during the time you encounter the Copy<=>Paste problem.

-- Ramesh, Microsoft MVP

Windows XP Shell/User

In the end, upgrading to the RDP 6.0 client also fixes this problem in mstsc. Now that I have upgraded it, I no longer have this issue.

Monday, December 24, 2007

I was working in a project that was a windows application, but I decided to change it to a console application instead. I changed the type to console and selected Sub Main as my startup object. When I compiled it I got the fallowing error: Error 54 No accessible 'Main' method with an appropriate signature was found.

I expected problems because I knew I did not have the Sub Main defined in my project. I added a class file and entered the fallowing code:

Public Class Main

Public Shared Sub Main()

Application.Run(New Form1)

End Sub

End Class

Several examples I saw had main defined with (ByVal args() As String) as the parameter. One thread on the subject indicated that you can add a module instead of a class. Here is the syntax for that.

Module Main

Public Sub Main(ByVal args() As String)

Application.Run(New Form1)

End Sub

End Module

You will notice that the shared keyword is left off inside the module.

Saturday, December 22, 2007

When mapping a drive, the full path of the share is displayed as the name of the drive. We have some very long path names and didn't want our users to see the details they didn't need. So I had to write a script to give those drives custom names.

Our login scripts contained lots of net use statements in *.BAT or *.CMD files. The command looked like this:

NET USE H: //server/share/directory1/directory2/directory3

and it would show in explorer like this:

directory3 on //server/share/directory1/directory2 (H:)

My goal was to make a script just as easy to use at NET USE. That is exactly what I ended up with. The new command looks like this:

By making the command simple the scripts are easy to read and modify by others on my team. Now that you know what we are doing, lets take a look at the code needed to make this work.

We are going to save this code with the name Map.vbs. Its a VBScript file executed by the windows scripting host. To make the script more usable, it needs to read the variables from the command line. The first 3 lines populate the variables we will use later.

This will map the path strPath to the drive strDriveLetter. The true as the 3rd param is the same as using the /PERSIST param of NET USE. It saves the mapping in the profile.

Now we need to change the name of the mapping. This takes an existing share by drive letter and gives it a custom display name. This was one of the hardest pieces of code to find. The next 2 lines do just that.

If you put that all together you have a bare bones script to map a drive and rename it from the command line via a VBScript. In my next post, I plan on going more in depth into my map.vbs. I will show you how to check for an existing mapping on that letter and all the validation I added.

Tuesday, December 18, 2007

I had some files that I wanted to embed into my project and access in code. I needed both images and xml files.

First you have to add the files to the project. I create the images in paint before importing them. The xml files were created within Visual Studio. Things started to look a little cluttered, so I created folders in the project to group them up.

Once the files are in place you need to open the properties for each one. Change the build action to "Embedded Resource". Now we can access the file streams from code.

Friday, December 14, 2007

I was working with events in C# and ran into this exception. System.NullReferenceException was unhandled Message="Object reference not set to an instance of an object." This exception was at the exact point in my code where I attempted to raise the event. It turns out that if there are not event handlers attached to your event, an attempt to raise it will give you this exception. To solve it, you have to check to see if its null before raising it.

Friday, December 07, 2007

This uses the default EventHandler that returns a object source and a EventArgs ex. If you want to pass back different parameters, you will need to create your own delegate. The delegate we just used looks like this:

public delegate void EventHandler (object source, EventArgs ex);

We dont have to define it because .NET already defined it for us. Here is a second example where we built a custom delegate and raise it.

Have you ever ...

Have you ever had a problem that is hard to search on? Some key words generate too many unrelated results. Other problems may be so basic that it’s just expected everyone will know it. I often run into problems that I expect others to have but nobody talks about it or just accepts that’s the way it is.

When I run into something that felt like it was harder to find then it should be, I will post it here. I don't have a set theme and many of my solutions are unrelated. But I hope you were able to find the solution to your problem within the pages of my blog.