Tuesday, November 03, 2009

Remote Desktop using C#.Net

Overview:
Remote Desktop Services is one of Microsoft Windows components to access a remote computer through network. Only the user interface of the application is presented at the client. Any input is redirected over to the remote computer over the network. At work we use Remote Desktop a great deal. It allows us to login to a remote server to perform health checks, deploy applications, troubleshoot problems, etc. We also use remote desktop often when we do WFH (work from home :)).

Why do we want to write a .Net application to do this when you have the MS Terminal Services client available from OS? Well, consider if you want to work on 3 different application servers at the same time and want to toggle between these 3 servers quite often. With the MSTSC, we will be running 3 different clients for the 3 servers and it is difficult to manage the working environment. In .Net you can develop an application with tab control to load remote desktop sessions in different tabs in one window.However, tab control is not in scope of this article. That gives me an idea for my next article :)

Microsoft Terminal Services Control

We will be using AxMSTSCLib an ActiveX component in our program to connect to the remote computer. It's not that hard to build a remote desktop application in .Net.
Microsoft has a "Microsoft RDP client control" ActiveX control that we will be using in our application.

This is how we do it

We will start by creating a windows application in the Visual Studio IDE.
Add reference to "Microsoft Terminal Services Control Type Library" from the COM tab. This will add MSTSCLib.dll to the project.





To add MSTSC to the toolbox, right click the toolbox and select "Choose Items…". Now add "Microsoft Terminal Services control from the COM tab.





Drag the newly added control from toolbox to the form.
Add 3 textbox and 2 button controls to the form.


Connect Button - Click Event:
Here is how we write the Connect button click event.

rdp.Server = txtServer.Text;
rdp.UserName = txtUserName.Text;

IMsTscNonScriptable secured = (IMsTscNonScriptable)rdp.GetOcx();
secured.ClearTextPassword = txtPassword.Text;
rdp.Connect();


Now assign the properties (Server, UserName) of RDP control with the textbox values.
Here's how easy to login to remote machine. However there is one catch, there is no direct method in RDP control through which you can pass the username and password to login to the remote desktop.
Due to security reasons you have to implement an interface (IMsTscNonScriptable) to cast it separately.

IMsTscNonScriptable secured = IMsTscNonScriptable)rdp.GetOcx();
secured.ClearTextPassword = txtPassword.Text;


Disconnect Button - Click Event:

To disconnect from the remote desktop session, we just need to call the Disconnect() method.
Before disconnecting, we want to ensure that the connection is still available. We don't want to disconnect if it is already disconnected (very clever huhJ)

if (rdp.Connected.ToString() == "1")
rdp.Disconnect();


Check the full source code here. Please leave your valuable comments and questions.
That's all folks! Happy Coding!

Friday, January 19, 2007

Snap It! - How to take screen shot using .Net

Introduction

We all would have used snap shots (screen shots) to illustrate bugs or behavior or something that others could understand by seeing them. For taking snap shots we just hit the "Print Screen" key and copy it to Ms Paint and save it. Ever wondered how to programmatically take a snap shot? Then this article is for you.

Image-1 This is how the application looks

Scenario


Why do we need to take snapshots programmatically? Consider a scenario where you want to report some kind of behavior errors in an application. Human supervision is not possible when the occurrence of error is random. So we just code a program to take snap shots are regular intervals and store it as a image file. So that later you can use it.

GDI classes we need to know

Lets see what we need to know before we do coding. We need to have a little knowledge about GDI and graphics classes. The Graphics class provides methods for drawing objects to the display device. A Graphics object is associated with a specific device context. This class is used as a canvas to draw images. In order to display anything in a window, you have to obtain a reference to the window's Graphics object.


Next comes the Bitmap class. A Bitmap object is an object used to work with images defined by pixel data. A bitmap consists of the pixel data for a graphics image and its attributes.

Getting Started


To use the GDI classes we need to include System.Drawing.Imaging namespace in the "using" section of the code. Go to the source view and add a string variable and a property to the class. This string variable is used in the property to store and retrieve the output file name.

// variable to store output file name
private string strFilename;
// Property for storing and retrieving output file name
public string filename
{

get{return strFilename;}
set{strFilename=value;}
}


In the design view, add a button and a savefiledialog to the form. Double click the button and go to the click event in the code view. Use the savefiledialog control to retrieve the output file name from the user. And store the file name in the variable strFilename using the property filename.

// Check user clicked OK button
// Get the filename and put in the textbox and property
if(saveFileDialog1.ShowDialog()!=DialogResult.Cancel)
{

filename=saveFileDialog1.FileName;
}


Before taking the snap shot we hide our application because we don't want our application in the snap shot image. Sometimes even after hiding the application, the snap shot pictures our application, this is because the application takes few extra milliseconds to hide, so we make our application to wait for some milliseconds.

this.Hide();
// Slow the thread to hide the application before taking the snap
Thread.Sleep(200);

How to Snap It?

Now we create a Bitmap object to set the size of the screen. We use the width and height of the application screen to capture the snap shot. So the user can place our application screen on any area of the screen, move/resize to get the snap shot. To make the user more comfortable in selecting the snap shot area we make the application screen semi-transparent by setting the opacity of the form to 50%

Resizing the application
Image-2 Resizing and Moving the screen


// Setting the size of the screen for the bitmap Bitmap bmp= new Bitmap(this.Width,this.Height,PixelFormat.Format32bppArgb);


A Graphics object is required to get the image bounds and create the actual picture. So we initialize a Graphics object and get the image bounds from the Bitmap that we have already created. CopyFromScreen method is used to get the snap shot from the screen. Based on the user selection of the file type in the savefiledialog box, we use different image formats to save the file using Bitmap.Save function.

// Saving file in the selected image format
bmp.Save(filename,ImageFormat.Jpeg);

After saving the picture we show the application back by using the following statement

// Showing the application again this.Show();

Viewing the snap shot


Now the screen is captured and the picture is saved. We need to view the snap shot. There is an option available to see how your snap shot has come up, just right after saving the file. We use Process class of System.Diagnostic namespace to view the image file.

// Viewing the image
Process pr= new Process();
pr.StartInfo.FileName=filename;
pr.Start();

Viewing the imageViewing the image
Image -3 Viewing the saved image file

When the Start method is executed the image file is opened in the respective application configured in the system.
Thats all folks.

Monday, January 15, 2007

File Splitter in .Net



Introduction

I love to do utility programs in .Net. And this is one of them. As I was playing with JSplit (a free file splitter program), I wondered if I could do it in .Net. The framework supports file operations like reading files in bytes and creating them. It is indeed easy to do file operations in .Net Basics on File operations
The namespace System.IO provides classes for file operations. StreamReader is a class which provides methods to read a file in different modes. It allows the user to read file by number of characters, by line, by block and to the end of the file. There is another class FileStream which allows the user to read file by number of bytes. This is what we are going to use.




Getting Started

Lets begin by creating a windows application with a textbox, a numericupdown control, a label and three buttons. Add a openfileDialog control and add some code to extract the filename from the dialog and to put it in the textbox when the browse button is clicked.
if(openFileDialog1.ShowDialog()==DialogResult.OK) { txtFileName.Text=openFileDialog1.FileName;
Now change the Maximum value of the numericupdown control to 1. Change the backcolor of the label to black and forecolor to green (to give a matrix screen effect)

Set the text property of the buttons to "Calculate" and "Split".

Include the namespaces System.IO and System.Text in the Using section.

Calculate Method

In Calculate method we are going to calculate the number of parts the file will be splitted based on the file size and the split size specified by the user.

Double click on the calculate button to go to the Click event. Now initialize the class FileStream by passing the filename from the textbox and specifying file mode and file access parameters.

FileStream FR=new FileStream(txtFileName.Text,FileMode.Open, FileAccess.Read);

The number of parts is caculated by dividing the file size (in bytes) and user selected split size. This is made to display in the label.

int no_of_parts = Int32.Parse(FR.Length.ToString())/intByteSize;
int intmod=Int32.Parse(FR.Length.ToString())%intByteSize;

//Include the remaining bytes
if(intmod > 0)
no_of_parts=no_of_parts+1;


Split Method

In this method we are going to split the file in to user desired size and number of parts. We again use the FileStream class to read the file. But here we are going to read the file by number of bytes required for each part. So after reading a block of bytes required for a part we write it to a file by using FileStream but in the create file mode and write file access.

//Read the file by number of bytes and create part files for(int i=0;i { if(intmod>0 && i==no_of_parts-1) { by=new byte[intmod]; FR.Read(by,0,intmod); } else { by=new byte[intByteSize]; FR.Read(by,0,intByteSize); }

FileStream's WriteByte function is used to write the bytes to a file. Like this number of files are generated for the number of parts calculated. Each file is written with a dynamic name by appending some incrementing number to the file name.

foreach(byte b in by)
{
FW.WriteByte(b);
}


Batch File

The significance of a file splitter is the ability to reunite the file without the actual splitter application. For this, we create a batch file in the split function to reunite the files and create the actual file. This batch file contains statements to combine the part files and generate the actual file.

StringBuilder SB= new StringBuilder(); SB.Append("Copy /b " + tempfilenames + " \"" + filename + "\""); SW.Write(SB.ToString());


We use StringBuilder class to generate the statement for the batch file. The statement includes the command for uniting the files followed by the filenames. This command should be dynamically added to include the filenames. Now we write this statement to a file and save. The content of the batch file should look like the following statement.

Copy /b "test.pdf0" +"test.pdf1" +"test.pdf2" "test.pdf"



Conclusion
While using file operations we should ensure that the file is closed after the read/write process. Thats all folks!
For further reading and code download

Thursday, December 21, 2006

Find and Replace for multiline text



Many of us would have used "Find and Replace" option available in our IDE and in many of the text editors. This functionality finds a single line of text given and replaces with the given text in the current document as well as in the files under a given folder. But how would you find and replace a multiline text? In this article I have tried to explain that.


The project included in this article has a simple file reading operation. For the beginners first let me explain how to read files. You can skip this section if you are familiar with file operations.

File Operations

The first step is to include the System.IO namespace in the using directive.

using System.IO;

System.IO namespace has DirectoryInfo class which is used for typical operations such as copying, moving, renaming, creating, deleting and enumerating through directories and sub-directories. Files under a specific directory can be found using this class.

The following statement instantiates DirectoryInfo class with a folder path from the text box.

DirectoryInfo DI= new DirectoryInfo(txtFolder.Text);

To get the file information we use the following statement.

foreach(FileInfo FI in DI.GetFiles())

The GetFiles method of the DirectoryInfo class, returns an array of FileInfo object. The FileInfo class like DirectoryInfo has operations for reading, copying, moving, renaming, creating and deleting files.

Now we use a StreamReader object to read the file.

StreamReader SR= new StreamReader(FI.OpenRead());

We use the following statement to read a line and assign it to a string variable.

s=SR.ReadLine();

Search Operation

We read each line and store it in a temporary variable appending a new line character ("\r\n") at the end of the line.
This will differentiate each line for searching multiline text.

temp=temp+s+"\r\n";

Now to search the string we use IndexOf() method in the temporary variable with the search text as parameter.

pos=temp.IndexOf(txtFind.Text);

The above statement returns the position of the search text.
We use a list box to record the number of files that matches the search text and the occurence of the first position.

Replace Operation

For the replace functionality, we use Replace() method in the temporary variable with search string and string to replace as arguments.
temp=temp.Replace(txtFind.Text,txtReplace.Text);

To reflect this change in the actual file, we need to write it to the file. So we use StreamWriter object to write to the file.

StreamWriter SW= new StreamWriter(FI.OpenWrite());
SW.Write(temp);
SW.Close();
The source code for the project can be downloaded here.
For further reading and source code download
Thats all folks!!!

Thursday, November 16, 2006

Consuming a webservice from behind a proxy firewall

I was trying to access a webservice from my office which is behind a proxy firewall, I was annoyed by seeing the following error message

"- The request failed with HTTP status 407: Proxy Authentication Required"

I knew that it is something to do with the firewall proxy. So I googled my doubt and the error text but couldn't get a descent solution. Then I tried with the options in the command WSDL that we use to generate a proxy class (not to be confused with firewall proxy) for our webservice.

I found the following options.

/proxy:
/proxyusername:
/proxypassword:
/proxydomain:

But I didn't know how to use these options (I should admit that I am not good at DOS). Then I googled these options and got some answers which I am going to share with you now.

/proxy: is the url of the proxy server with the port number. For E.g., if your proxy server address is 255.255.255.255 and the port is 8001 then your proxy url is http://255.255.255.255:8001

/proxyusername: is the username of your proxy server and /proxypassword: is the password of your proxy server.

/proxydomain: is the domain name of your server.

So the WSDL command should be something like this.

c:\WSDL /proxy:http://255.255.255.255:8001
/proxyusername:uname
/proxypassword:pwd /proxydomain:lotus http://thiagu007.tk.105.webhostforasp.net/
service1.asmx?wsdl

The above command will download the proxy class file for the webservice.

But this is not the end of the show. We need to consume the service. The first thing we need to do is compile the class to a dll.

c:\csc.exe \t:library service1.cs

Then create a windows application project in Visual Studio and add the dll as a reference. Now you can use the class that is available in the dll and create an instance of it. But calling the web method from the webservice will again display the same error.

To resolve this you have to create a WebProxy. This is again the authenication information for firewall proxy.

To instantiate the WebProxy class you need to include the namespace System.Net in the "using" part.

using System.Net;

Now you can instantiate WebProxy class as follows,

// Instantiate the WebProxy class
WebProxy myProxy = new WebProxy(http://255.255.255.255:8001,true);
myProxy.Credentials = new NetworkCredential("uname", "pwd", "lotus");

Now, the proxy should be assigned to the Service class and the function can be called.

// Instantiate the WebService class
Service1 sr=new Service1();
sr.Proxy =myProxy; // Set the proxy to the class
String str=sr.HelloWorld(); // Calling the web method

This will call the method that is available in the webservice by authenticating the proxy server's credentials.

Happy Coding :)

Monday, November 06, 2006

Dynamic Code Compilation

Welcome to dynamic code compilation. This article throws light on how a code can be built dynamically, compiled and run. The scenario of dynamic code compilation may arise when you want an application to upgrade (or rewrite) another application.
Lets jump in to coding. The namespaces that we are going to use in this project are
  • System.CodeDom
  • System.CodeDom.Compiler
  • Microsoft.CSharp
The System.CodeDom namespace contains classes that can be used to represent the elements and structure of a source code document. The classes in this namespace can be used to model the structure of a source code document that can be output as source code in a supported language using the functionality provided by the System.CodeDom.Compiler namespace.

The Microsoft.CSharp namespace contains classes that support compilation and code generation using the C# language.

At first we need to instantiate the class CSharpCodeProvider. Then create a complier using CreateCompiler() function of CSharpCodeProvider class and assign to the interface ICodeCompiler.

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();

Then set the parameters for the compiler using CompilerParameters class. Set parameters like GenerateExecutable, OutputAssembly

System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = "Out.exe";

Now declare a String variable and write the source code for the new application/program. Now instantiate CompilerResults class with compiler parameters and the source code as below.

String sourcecode;
sourcecode="using System;namespace SampleApp{class Class1{[STAThread] static void Main(string[] args) { Console.WriteLine(\"I am born to live!\");Console.Read(); } }}";
CompilerResults results = icc.CompileAssemblyFromSource(parameters,sourcecode);

Now the code is compiled. If you want to run the compiled EXE, start the process by

Process.Start("Out.exe");

Thats all folks!....
Happy coding

Wednesday, July 12, 2006

Calling APIs, The .Net Way!

What is Windows API?

The Windows API is the name given by Microsoft to the core set of application programming interfaces available in the Microsoft Windows operating systems. It is designed for usage by C/C++ programs and is the most direct way to interact with a Windows system for software applications.

The functionality provided by the Windows API can be grouped into various categories like Base Services, Graphics Device Interface, User Interface, Common Dialog Box Library, Common Control Library, Windows Shell, Network Services.


The .Net Way!


Now we will see how to call an API function in .Net. As we all know that .Net supports Interop Services, its very easy to call an API function using the namespace "System.Runtime.InteropServices".

Before going to the coding section, lets start with an example. Here I am going to use Windows API for hiding the mouse cursor and showing it back. For this purpose, I am going to use the API user32.ShowCursor function which is under the category User Interface.

Let us start the coding by first including the namespace "System.Runtime.InteropServices". This namespace provides a wide variety of members that support COM interop and platform invoke services.


using System.Runtime.InteropServices;

Then comes the declaration part. Here we declare the API function that we are going to use. Here we have to specify the dll to which the function refers. In our case it is User32.dll.

[DllImport("user32.dll")]
static extern int ShowCursor(bool bShow);

The Statement DllImport is an attribute which you use to define platform invoke methods for accessing unmanaged APIs. This definition should be made inside the main class like other member functions and variables.

The interesting part is calling the API function. It is very straight forward. Just use the following statement.

ShowCursor(false); // Hide cursor

ShowCursor(true); // Show cursor

Some Tips...

For beginners, implementing APIs is a tough job. There is a quick reference website (www.pinvoke.net) which provides the structure and sample code (sometimes) for all the APIs. But first you need to know which API function is needed for your use. You can find it easily by searching in Google. Happy Coding!