Sunday, November 22, 2009

Remoting server in c#

Create a remoting object (who's methods are RPC) over TCP like this on the server:
MyRemotingObject LocalRemotingObject = new MyRemotingObject();
LocalRemotingObject.MySetupBeforePublishing();
ChannelServices.RegisterChannel( new TCPChannel( MyPort ), false );
ObjRef LocalRef = RemotingServices.Marshal( LocalRemotingObject, "MyRemotingService" );

You can then use LocalRemotingObject like a normal object with straight function calls on the server. Clients use it as normal - with Activator.GetObject() to get a proxy. To destroy the remoting object:
RemotingServices.Unmarshal( LocalRef );
RemotingServices.Disconnect( LocalRemotingObject);
LocalRemotingObject = null;

Some benefits with this approach (instead of using RegisterWellKnownServiceType):

  1. Function call performance on the server is optimal.
  2. You control the time of creation/destruction of the server object explicitly.
  3. You can call functions on the LocalRemotingObject before it has been published as a service, without having to worry about clients trying to use the object at the same time. (Like the call to MySetupBeforePublishing above.)
  4. Using these methods, you can shutdown and restart your remoting service at runtime.

Saturday, November 21, 2009

Visual Studio: What is "MyApplication.vshost.exe" for?

The MyApplication.vshost.exe file is generated by Visual Studio. The IDE uses it for improved F5 performance, partial trust debugging, and design time expression evaluation. You should not include this file when deploying/installing your application. It's not required for just running the stand-alone application since it's only used while working within the Visual Studio IDE.

You can disable the generation and usage of vshost in the application settings: "Enable the Visual Studio hosting process" under the "Debug" tab. You'd lose the benefits mentioned above, of course.

More information here: dtemp's WebLog

Saturday, November 14, 2009

Finding child windows in c#

If you have a IntPtr window handle (e.g. by using Process.MainWindow), the following helper functions lets you find any of its child windows by class name and/or window title, recursively:

/// 
/// Uses FindWindowEx() to recursively search for a child window with the given class and/or title.
/// 
public static IntPtr FindChildWindow( IntPtr hwndParent, string lpszClass, string lpszTitle )
{
 return FindChildWindow( hwndParent, IntPtr.Zero, lpszClass, lpszTitle );
}


[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

/// 
/// Uses FindWindowEx() to recursively search for a child window with the given class and/or title.
/// 
public static IntPtr FindChildWindow( IntPtr hwndParent, string lpszClass, string lpszTitle )
{
 return FindChildWindow( hwndParent, IntPtr.Zero, lpszClass, lpszTitle );
}

/// 
/// Uses FindWindowEx() to recursively search for a child window with the given class and/or title,
/// starting after a specified child window.
/// If lpszClass is null, it will match any class name. It's not case-sensitive.
/// If lpszTitle is null, it will match any window title.
/// 
public static IntPtr FindChildWindow( IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszTitle )
{
 // Try to find a match.
 IntPtr hwnd = FindWindowEx( hwndParent, IntPtr.Zero, lpszClass, lpszTitle );
 if ( hwnd == IntPtr.Zero )
 {
  // Search inside the children.
  IntPtr hwndChild = FindWindowEx( hwndParent, IntPtr.Zero, null, null );
  while ( hwndChild != IntPtr.Zero && hwnd == IntPtr.Zero )
  {
   hwnd = FindChildWindow( hwndChild, IntPtr.Zero, lpszClass, lpszTitle );
   if ( hwnd == IntPtr.Zero )
   {
    // If we didn't find it yet, check the next child.
    hwndChild = FindWindowEx( hwndParent, hwndChild, null, null );
   }
  }
 }
 return hwnd;
}

Friday, November 13, 2009

Blog purpose

This blog is about coding tips and ideas I've come across while playing around at home.