Archive for the ‘Delphi XE2’ Category

Creating a Remote Desktop Plugin Using Delphi - Errata

Wednesday, January 9th, 2013

After I had implemented my plugin and it was just going into production, I discovered a rather ugly truth.  WTSVirtualChannelOpen will succeed even if the plugin is not installed on the client side.  You don’t find out about the problem until the first time you try to write to the channel, whereupon you get an obscure error.  Something about an “invalid function”.

It appears as though the only solution to this problem is to implement a “ping” function in the plugin. Then, on the server side, you need to open the virtual channel and ping the client.  If both of these succeed then the plugin exists, otherwise it does not.

You would think that Microsoft would at least check to see if the client has registered the virtual channel before returning a handle for it.

Creating a Remote Desktop Plugin Using Delphi - Part 5

Tuesday, December 4th, 2012

The last thing that I need to do to my remote desktop plugin is add the code required to send data from the client to the server.

Creating a Remote Desktop Plugin Using Delphi - Part 4

Monday, December 3rd, 2012

Now that we have the client side ready to receive data from the server we need to look at programming the server side.  This actually seems to be quite a bit simpler that the client side.  There are just four functions; WTSVirtualChannelOpen, WTSVirtualChannelClose, WTSVirtualChannelRead and WTSVirtualWrite.  Actually, there are a few more, but these are the ones that you need to get by. (more…)

Creating a Remote Desktop Plugin Using Delphi - Part 2

Thursday, November 29th, 2012

In part 1 of this series I set about creating a remote desktop plugin using Delphi. It didn’t do anything except initialize itself and display a few message boxes indicating its progress.  Not very useful.

In order for this whole thing to work the way I want it to, the plugin is going to have to interact with the user on the remote workstation.  This means displaying a form that will have to be on top of the remote desktop window.  I had some vague misgivings that remote desktop in full screen mode would be an “always on top” window that would interfere with the interaction that I need. So, as the next step in the process, I changed the plugin to create a form, make it an “always on top” window and display my status messages in a TMemo contained in the form.  Surprisingly enough this actually works quite well.


Creating a Remote Desktop Plugin Using Delphi - Part 1

Saturday, November 17th, 2012

I have recently found myself in a situation where I need to have an application running on a server using remote desktop interact with files and devices on the user’s local workstation.  Specifically, I need to be able to use a scanner to scan documents and / or retrieve files containing documents that have already been scanned. I found several commercial plugins that would drive the scanner but I couldn’t find anything that would allow me to interact with the user to allow her to import documents from a file.

Knowing that there are commercial plugins available, I know that it is possible to write a plugin for remote desktop.  So, I’m thinking; “How hard can it be?”.  Since we are virtually a pure Delphi shop I started looking for examples of Delphi plugins.  Surprisingly, I didn’t find any.  It is difficult to believe that no one else has done this, but I seem to be a pioneer. So, in this and the next few articles, I am going to create a remote desktop plugin using Delphi and remote desktop virtual channels and I am going to document the process here.


Delphi Class Completion (Ctl-Shft-C) Stops Working

Sunday, March 18th, 2012

Suddenly, pressing Ctl-Shft-C in the Delphi XE2 IDE stopped working.  You could press that magic key combination all day and nothing would happen.  It took hours to figure out what the problem was.

I had installed update 4 for Delphi XE2, which contained, among other things, something called AQTime.  This appears to be some kind of application profiler.  Anyway, it was AQTime that was interfering with class completion.  A quick trip to Control Panel to uninstall the offending bit of software and everything went back to normal.

Never build package %s must be recompiled

Sunday, March 18th, 2012

I was recompiling my application they other day, switching everything from Debug to Release.  Suddenly I started getting “Never build package %s must be recompiled” errors.  I couldn’t understand this, since the previous step in the recompile had just finished compiling the package in question.

It finally turned out to be caused by recompiling the Release packages into a different directory than the Debug packages.  The Debug packages went into Delphi’s default DCP and BPL directories while the Release packages went into the projects ($Platform)\($Config) directory.  I did this because the packages in question contain Delphi components that appear in the component toolbar and I want to be able to step into the source for those packages while debugging.  I thought that compiling the Release packages to a different directory would solve all kinds of problems related to debugging.   And it did, but it created these errors when compiling for Release.  It was the order of directories on Delphi’s search path that caused the problem.  The Delphi wide options specify the default package directory early on in the search path.  Even though I had the Release directory on the project’s search path, the Release DCPs were never found, because the Debug DCPs were found first.  Since I was compiling the Release packages to ..\$(Platform)\($Config) all I had to do was add that to the Delphi wide search path before the default DCP directory and the problem was solved.