Archive for the ‘How To’ Category
.NET Type Forwarding – Moving Types Between Assemblies
I learned about this really cool feature in the .NET framework while reading an MS certification book, and could not stop blogging about it. Type forwarding in .NET allows you to move type from one assembly to another without recompiling applications that use the old assembly.
Important Notes:
- Microsoft Visual Basic 2005 does not support the use of the TypeForwardedToAttribute attribute to forward types written in Visual Basic 2005. Applications written in Visual Basic 2005 can use forwarded types written in other languages.
- The compilers do not support forwarding generic types in .NET 2.0, 3.0 and 3.5. Support for this was added in .NET 4.0.
For this example, I would write one assembly called Animal that would contain a class called Dog, which would be consumed by an application called Consumer1. Later, I would move the Dog class to a new assembly called Canine, and we would see how we can make the Consumer1 application still work using .NET type forwarding feature.
Animal (Class Library)
As discussed here is the Dog class that would reside inside the Animal assembly.
Dog.cs
namespace Animal
{
using System;
public class Dog
{
/// <summary>
/// Make the dog bark.
/// </summary>
public void Bark()
{
Console.WriteLine("Arrgh.... Woof Woof!");
}
}
}
It’s a very simple class that contains a public method called Bark, which would output "Arrgh…. Woof Woof!" to the console when invoked.
Consumer1 (Console Application)
I would now write our first application that would consume the animal assembly. Its a simple console application that has reference to the Animal assembly.
namespace Consumer1
{
using System;
using Animal;
/// <summary>
/// The program.
/// </summary>
internal class Program
{
#region Methods
/// <summary>
/// The entry point.
/// </summary>
/// <param name="args">
/// The command line arguments.
/// </param>
private static void Main(string[] args)
{
Console.WriteLine("Consumer 1 Application");
Dog dog = new Dog();
dog.Bark();
Console.ReadKey();
}
#endregion
}
}
In the main method of the Consumer1 application I have created an instance of the Dog class and then called its Bark method. When we run this application we would get the following output.
Output:
Consumer 1 Application
Arrgh…. Woof Woof!
Canine (Class Library)
I moved the Dog class from Animal assembly to the new assembly called Canine.
namespace Animal
{
using System;
public class Dog
{
/// <summary>
/// Make the dog bark.
/// </summary>
public void Bark()
{
Console.WriteLine("Arrgh.... Woof Woof! (Inside New Assembly)");
}
}
}
The only difference in the class definition here, is the text that I output to the console when the Bark method is invoked. I have changed it so that we can easily spot out that our old application (Consumer1) is accessing the Dog class from the new Canine assembly.
Also you might wonder, if the assembly name is Canine then why is the namespace for the Dog class still Animal? It’s necessary to keep the old namespaces while moving types between assemblies for the old applications to find the type in the new assembly.
If we deploy the Animal assembly without the Dog class then existing installed applications that were compiled against the old Animal assembly would break. Unless, we use type forwarding in the modified Animal assembly and let it know where to look for the Dog class when its requested. To enable type forwarding we need to do the following things:
- Add a reference of the new Canine assembly to the Animal assembly.
- Add the TypeForwardedToAttribute attribute to the animal assembly and specify the type to be forwarded.
Normally we add all assembly attributes to the AssemblyInfo.cs file. The TypeForwardedToAttribute attribute resides in the System.Runtime.CompilerServices namespace. Add the following line to the AssemblyInfo.cs.
using System.Runtime.CompilerServices; // Type forward the dog class to the Canine assembly [assembly: TypeForwardedTo(typeof(Animal.Dog))]
When any application would look for the Dog class in the Animal assembly it would be forwarded to the Canine assembly. Now when we deploy the new Animal & Canine assembly though the Consumer1 application does not have a reference to the Canine assembly, it would still find the Dog class and produce the following output.
Output:
Consumer 1 Application
Arrgh…. Woof Woof! (Inside New Assembly)
Deploying both the assemblies are important. Otherwise the Consumer1 application will not find the Dog class, and would crash.
Source Code:
C# – Change log4net Log Path and Level Programmatically
Log4Net makes it incredibly easy to implement logging functionality in your application. Log4Net configuration can be little bit tricky, but its easy to learn.
Most of the time when I am working on a project the application configurations including log path and level are fetched from the database.
Log4Net doesn’t provide any straight forward way of fetching log file path or level from database (because its not necessary). To change the log file path and level programmatically we have to write our own log file appender.
For this demonstration I will write one rolling file appender. The custom file appender class should inherit from the log4net’s RollingFileAppender class. We have to override the File property of the appender and change the log path. My rolling file appender class looks like this:
My Rolling File Appender:
namespace MyLog4Net.LogAppenders
{
using System;
using log4net;
using log4net.Appender;
using MyLog4Net.Interfaces;
using MyLog4Net.Services;
/// <summary>
/// My log4net Rolling file appender.
/// </summary>
public class MyLog4NetFileAppender : RollingFileAppender
{
#region Constants and Fields
/// <summary>
/// Component parameter business layer
/// </summary>
private static IConfigService service;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="MyLog4NetFileAppender"/> class.
/// </summary>
public MyLog4NetFileAppender()
: this(new ConfigService())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MyLog4NetFileAppender"/> class.
/// </summary>
/// <param name="configService">
/// The config service.
/// </param>
public MyLog4NetFileAppender(IConfigService configService)
{
service = configService;
// get the log level
// must be a proper log4net Threshold
string logLevel = service.GetLogLevel();
// set the log level
LogManager.GetRepository().Threshold = LogManager.GetRepository().LevelMap[logLevel];
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the log file name.
/// </summary>
/// <value>The log file name.</value>
public override string File
{
get
{
return base.File;
}
set
{
try
{
// get the log directory
string logDirectory = service.GetLogPath();
// get the log file name from the config file.
string logFileName = value.Substring(value.LastIndexOf('\\') + 1);
// build the new log path
if (!logDirectory.EndsWith("\\") || !logDirectory.EndsWith("/"))
{
logDirectory += "\\";
}
// replace the new log file path
base.File = logDirectory + logFileName;
}
catch (Exception ex)
{
// TODO: Log the error
// use the default
base.File = value;
}
}
}
#endregion
}
}
Setting The Log Level (Threshold):
public MyLog4NetFileAppender(IConfigService configService)
{
// Service layer that will be used to fetch config data
service = configService;
// get the log level
// must be a proper log4net Threshold
string logLevel = service.GetLogLevel();
// set the log level
LogManager.GetRepository().Threshold = LogManager.GetRepository().LevelMap[logLevel];
}
In the constructor of this class I fetch the log threshold configured in the database using the service.GetLogLevel() method. The LogManager.GetRepository() returns the default log4net repository of the calling assembly. LogManager.GetRepository().LevelMap gives us a set of default log4net levels. We change the log level by pasing the value fetched from the database to the current repositories Threshold property.
Setting The Log Path:
public override string File
{
get
{
return base.File;
}
set
{
try
{
// get the log directory
string logDirectory = service.GetLogPath();
// get the log file name from the config file.
string logFileName = value.Substring(value.LastIndexOf('\\') + 1);
// build the new log path
if (!logDirectory.EndsWith("\\") || !logDirectory.EndsWith("/"))
{
logDirectory += "\\";
}
// replace the new log file path
base.File = logDirectory + logFileName;
}
catch (Exception ex)
{
// TODO: Log the error
// use the default
base.File = value;
}
}
}
When log4net is initializing the File property of the file appender would be called. Here the value would be the file name that was set in the log4net configuration file. In this property we extract the file name and then append the log path that we fetched from the database.
Using Our Custom Appender:
To use our custom appender we would create a log4net appender section in the config file and use our appender in the appender type. I like placing my log4net configuration is a different file. My log4net configuration file looks like:
Log4Net Configuration File:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<!-- log4net -->
<log4net>
<!-- Define some output appenders -->
<appender name="MyRollingFileAppender" type="MyLog4Net.LogAppenders.MyLog4NetFileAppender">
<param name="File" value="..\\Log\\MyApplication-log-file.txt" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header] " />
<param name="Footer" value="[Footer] " />
<param name="ConversionPattern" value="%d [%t] %-5p %C %M - %m%n" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<!-- Setup the root category, add the appenders and set the default level
ALL
DEBUG
INFO
WARN
ERROR
FATAL
OFF
For example, setting the threshold of an appender to DEBUG will also allow INFO,
WARN, ERROR and FATAL messages to log along with DEBUG messages. (DEBUG is the
lowest level). This is usually acceptable as there is little use for DEBUG
messages without the surrounding INFO, WARN, ERROR and FATAL messages.
Similarly, setting the threshold of an appender to ERROR will filter out DEBUG,
INFO and ERROR messages but not FATAL messages.
-->
<root>
<level value="ALL" />
<appender-ref ref="MyRollingFileAppender" />
</root>
</log4net>
</configuration>
Notice that instead of using log4net’s RollingFileAppender class I am using our MyLog4NetFileAppender class.
Initializing Log4Net:
To initialize log4net put the following code in the AssemblyInfo.cs file.
/* Configure log4net log4net configuration will be searched in the .config file*/ [assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
The above code tells log4net to look for log4net.config file in the application and initialize itself.
Now everything is ready you can now run your application. To check if the code works or not you can put breakpoints in the constructor and File property of the appender.
Source:
Download the source code for this article MyLog4Net.zip
Building The E-TextEditor On Ubuntu 9.04 64 Bit
E-TextEditor a.k.a e is my favorite text editor on windows. AFAIK there is no text editor on linux that matches what e can do except for VIM. When I saw the post about making e open source I was pretty exited and wanted to try it out.
So I grabbed the source from GitHub and thought of building it. I am making this post to explain all the problems that I faced while building e. You may or may not face the same problem or you may face different problem altogether, so good luck.
Grab The Source
Download the latest source code from http://github.com/etexteditor/e/tree/master using the download button available or by using git tool to clone the repository.
Extract the source code somewhere and open the linux-notes.txt in your favorite text editor.
Downloading & Building E-TextEditor
I am a linux n00b so I choose the easiest way to build e according to linux-notes.txt
# The easiest way to build is to use the supplied scripts (example shows debug build): cd external sudo ./get-packages-ubuntu.sh bakefile ./get_externals_linux.sh ./build_externals_linux.sh debug cd .. cd src make DEBUG=1 ./e.debug
I face problem while getting external packages for linux and while building WebKit. The problem was get-packages-ubuntu.sh was unable to install libwxgtk2.8-dev due to header mismatch (Sorry but I don’t remember the exact error. I guess it includes wxWidgets header files) and the link to download tomcrypt and tommath libraries were not found.
I had to download wxWidget headers from their site. I downloaded the amd64 package because I am running Ubuntu 9.04 64 bit
http://apt.wxwidgets.org/dists/jaunty-wx/main/binary-amd64/wx2.8-headers_2.8.10.1-1_amd64.deb
The url’s mentioned in get-external-linux.sh to download tomcrypt and math libraries didn’t resolve because libtomcrypt.com is down at the moment.
wget -nc http://libtomcrypt.com/files/crypt-1.11.tar.bz2 wget -nc http://math.libtomcrypt.com/files/ltm-0.39.tar.bz2
So I had download the crypt-1.11.tar.bz2 and ltm-0.39.tar.bz2 files from http://safari.iki.fi/tom/. You need to be careful here download the exact version mentioned in the script or else it won’t compile.
Now that we have all the dependencies we are now ready to install them and then we can build e.
Install The Dependencies
Double click on the wx2.8-headers_2.8.10.1-1_amd64.deb file and then click on Install Package button to install the file.
Now its time to fix problems in get_external_linux.sh file. If you can write your own script after reading get_external_linux.sh its great, but I am lazy so I just created the arch directory inside the external directory and copied all the files that were supposed to be downloaded by the _download function.
_download()
{
# Download external libraries
echo "Downloading external libraries..."
echo
pushd arch
wget -nc http://libtomcrypt.com/files/crypt-1.11.tar.bz2
wget -nc http://math.libtomcrypt.com/files/ltm-0.39.tar.bz2
wget -nc http://www.equi4.com/pub/mk/metakit-2.4.9.7.tar.gz
wget -nc ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.6.tar.gz
wget -nc http://kent.dl.sourceforge.net/sourceforge/tinyxml/tinyxml_2_5_3.tar.gz
wget -nc http://biolpc22.york.ac.uk/pub/2.8.10/wxWidgets-2.8.10.tar.bz2
wget -nc http://builds.nightly.webkit.org/files/trunk/src/WebKit-r43163.tar.bz2
popd
}
I actually downloaded all the files mentioned in the _download function to some location to save me download time just in case if anything goes wrong. You may copy only the missing files and the script will download rest of the files.
Now run the get_external_linux.sh file again by issuing the command ./get_external_linux.sh.
Everything would work fine after this step (worked fine for me). Now issue rest of the commands
./build_externals_linux.sh debug cd .. cd src make DEBUG=1
It will take sometime to complete all these commands. If you get any error here that mean something is wrong with the code and you are missing a patch. All you need to do now is Google the error or fix it yourself or post it here and wait for somebody to answer.
If everything goes fine as expected you can now see e.debug. But as you can see the size of e.debug file is more than 200MB use the strip command to remove all debug information.
# source : http://fixnum.org/blog/2009/e_on_fedora strip e.debug -o e.stripped
Now you will have a e.stripped executable weighing approximately 26MB.
Getting Themes & Bundles
E-TextEditor will not run without the Themes & Bundles. So it needs to be downloaded and placed inside .e folder in your home directory. Issue the following commands to download and export e themes and bundles.
Install Subversion if you haven’t already.
sudo apt-get install subversion svn checkout http://ebundles.googlecode.com/svn/trunk/ ebundles-read-onlysvn export ebundles-read-only ~/.e/
You will see an message Export Complete. Now you can run the e.stripped or e.debug and e should run.

Though I was able to build and run E-TextEditor on my machine but its pretty much useless, it has got lots of bugs and it keeps crashing. I still have to download patches from e repository and rebuild my source.
Hope it helps
Installing Adobe Air and TweetDeck on Ubuntu 9.04 64 Bit
After installing Ubuntu 9.04 x64 when I installed Adobe AIR and TweetDeck it all got installed normally, but TweetDeck or any other AIR application didn’t work.
As of now Adobe AIR binaries are not available for 64 bit OS. However, Adobe AIR 32 bit will work if 32 bit libraries and packages are installed. To install Adobe AIR on a 64 bit OS follow these instructions.
Download Adobe AIR Installer
Download the Adobe AIR Installer from http://get.adobe.com/air/
Download 32 bit Files
Now you need to install all the 32 bit dependencies. To do so use the getlibs utility from http://frozenfox.freehostia.com/cappy/ (thanks to Laurie Cope for the updated link)
After installing getlibs utility issue the following commands in the console.
zuhaib@NerdBox:/$ sudo apt-get install lib32asound2 lib32gcc1 lib32ncurses5 lib32stdc++6 lib32z1 libc6 libc6-i386 lib32nss-mdns zuhaib@NerdBox:/$ sudo apt-get install ia32-libs zuhaib@NerdBox:/$ sudo getlibs -l libgnome-keyring.so zuhaib@NerdBox:/$ sudo getlibs -l libgnome-keyring.so.0 zuhaib@NerdBox:/$ sudo getlibs -l libgnome-keyring.so.0.1.1
Install Adobe AIR
Open console and goto the change directory to the location where you downloaded Adobe AIR installer and issue the following commands.
zuhaib@NerdBox:~/Desktop$ chmod +x AdobeAIRInstaller.bin zuhaib@NerdBox:~/Desktop$ sudo ./AdobeAIRInstaller.bin zuhaib@NerdBox:~/Desktop$ sudo cp /usr/lib/libadobecertstore.so /usr/lib32
You are good to go now.
Sources
Preventing Or Removing Autorun.inf virus
How many times have you plugged in your removable drive into some pc and next time you insert your removable drive and you see an autorun command. You double click on the removable drive and bam your pc is infected. Sometimes the clicking on the Open and Explore command will also execute the virus and your pc will be infected.
When your flash drive is infected it normally contains two files autorun.inf and some executable file. The autorun.inf can be found in the root of your flash drive.
If your system is infected formatting the media also will not clean the virus and sometimes you can’t even show hidden files. When you try to show hidden files from the folder options it simply won’t work.
If you have ever faced such problems then read along. When I plug-in any removable media to my pc I follow few steps to avoid such malwares. Even if you get infected its easy to eliminating such viruses.
Prevention Is Better Than Cure
Method 1:
Disable Autorun by running this reg file. This will turn off the autorun feature.
Method 2:
If you do not want to turn off the autorun feature and still want to be safe then follow these few steps before opening any flash drive to avoid triggering the virus.
Do not double click and open your flash drive. Always open it from the explorer folder list.
This way you avoid triggering the virus via autorun.inf.
To check if your flash drive contains the virus. Open folder options from the tools menu. Select the View tab and select Show hidden files and folders radio button under the Hidden files and folders tree. Also uncheck the Hide protected operating system files (recomended) check box. Click on apply and the OK.
Now you should be able to view hidden files and folders. Open your flash drive and explorer from the explorer folder tree. If you see see autorun.inf file in the root of your flash drive then open it in notepad. Delete any executable file or batch files it is pointing to and then the autorun.inf file itself.
If you still can’t see the hidden files then open command prompt and type the command dir /AH to view all the hidden and system files.
If you get an access denied error while deleting the files then it means that you are already infected by the virus.
If Show Hidden Files & Folders option in the folder options dialog doesn’t work then follow the steps mentioned at the end of the post to fix this issue.
Manually Deleting The Autorun.inf Virus
If you can’t show hidden files or you are not able to delete the autorun.inf file and the executable then you are already infected by the virus. Now you need to manually delete the virus.
Step 1
The first place to look for the virus is the startup program list. Open Run dialog from the start menu and type msconfig and press enter. This will bring the System Configuration dialog box. Under the startup tab look for any suspicious unwanted program.
If you suspect any program then google the executable name and gather some information about it. Usually all the viruses copy themselves to the windows or system32 folders and sometimes to the root or program files.
After un-checking all the unwanted programs click Ok. The dialog will prompt you to restart for the changes to apply. Click on Exit without restarting. We still have some steps to complete.
Step 2
Some viruses hook into the shell. Open the run dialog from the start menu and type regedit and press enter, this will open the registry editing tool.
Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon using the tree in the left hand panel. Check the value of the Shell key.
The value of the Shell key should be explorer.exe if you see name of any other executable file along with the explorer.exe, double click on the Shell key and delete anything except the explorer.exe and click ok.
Now reboot your pc. After rebooting your pc you should now be able to delete the autofun.inf and any other virus that you were not able to delete before.
Folder Options – Fix For “Show Hidden Files & Folders” Not Working
Sometimes even after removing the virus you won’t be able to show the hidden files. After settings the options in the folder options they get back to the old settings. You need to do change another key in the registry to fix this problem.
Method 1:
Go to registry editor by running regedit in the run box.
Go to this key:
HKEY_CURRENT_USER\Software\Microsoft\
Windows\CurrentVersion\Explorer\Advanced
In the right hand area, double click hidden and change the value to 1.
Now you’re all set to go. Check it in your tools menu if the changes have taken effect.
Method 2:
1. Click “Start” -> “Run…” (or press Windows key + R)
2. Type “regedit” and click “Ok”.
3. Find the key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\
Advanced\Folder\Hidden\SHOWALL
4. Look at the “CheckedValue” key… This should be a DWORD key. If it isn’t, delete the key.
5. Create a new key called “CheckedValue” as a DWORD (hexadecimal) with a value of 1.
6. The “Show hidden files & folders” check box should now work normally.
Hope it helps
