Archive

Archive for February, 2010

Developing simple Windows 7 Gadget – Part 2

February 24th, 2010 Anuraj P No comments

In my last post I have created a simple Windows 7 Gadget for testing Regular expressions. In this post we look into the Gadget Options dialog and Gadget API, which helps to display the options dialog and save the preferences from the User. The options dialog is a nice feature used in Gadgets to manage the user preferences. It is also an HTML file. Unlike the main Gadget HTML file, which is specified in the XML Definition file, the Options HTML File is specified in the main gadget file or in the main Javascript file, generally in the gadget initialization area of your script. In the RegEx Tester example, I am using the RegEx function flags as customization options.

RegEx Tester Settings

RegEx Tester Settings

So I have created an HTML File with 3 checkboxes and wrote a javascript function to get the user selected options, create the flags variable, and when closing the Options dialog, save the user preferences. To create the settings or options dialog, set the SettingsUI property.

System.Gadget.settingsUI = "settings.html";

After setting the SettingsUI property, the Gadget will display a Options button in the Gadget handle.

Settings Button

Settings Button

The Gadget API also supports various events / callback functions for the Options dialog, like SettingsClosing, SettingsClosed etc, which helps to save the Preferences and Read the preferences in the Gadget.

System.Gadget.onSettingsClosed = settingsClosed;
function settingsClosed(event) {
	//OK Button clicked.
if (event.closeAction == event.Action.commit) {
	//Load settings here.
}
}

Gadget API supports various methods to read and write settings. For writing setting we can use System.Gadget.Settings.write or System.Gadget.Settings.writeString. Both the functions will expects a key/value pair. And for reading can use System.Gadget.Settings.read or System.Gadget.Settings.readString, both of these functions take a key and return a value. If the key does not exist (for instance if it has never been written) both will return a value of undefined. Use System.Gadget.Settings.xxxxString method, if you are working with string values. All the settings are stored in Settings.ini file. And it is available in the “C:\Users\\AppData\Local\Microsoft\Windows Sidebar” location.
Saving the preferences

System.Gadget.Settings.write("RegExOptionsSaved", "true");
System.Gadget.Settings.write("RegExOption", escape(result));

And reading the Preferences 

if (System.Gadget.Settings.read("RegExOptionsSaved")) {
regExOptions = unescape(System.Gadget.Settings.read("RegExOption"));
}

RegEx Object constructor 

var re = new RegEx("Pattern","Flags");

And the Flags are

  1. Global Search – g – The global search flag makes the RegExp search for a pattern throughout the string, creating an array of all occurrences it can find matching the given pattern.
  2. Ignore Case – i – The ignore case flag makes a regular expression case insensitive. For international coders, note that this might not work on extended characters such as å, ü, ñ, æ.
  3. Multiline Input – m – This flag makes the beginning of input (^) and end of input ($) codes also catch beginning and end of line respectively.

Developing simple Windows 7 Gadget – Part 1

February 24th, 2010 Anuraj P No comments

Gadgets are simple and lightweight applications, which can be developed using HTML, Javascript and CSS. Gadgets can also include Image files. In Windows Vista, we can create Gadgets by zipping the files, and rename the it with .Gadget extension. In Windows 7 we can create Gadget by creating the .Gadget folder in C:\Program Files\Windows Sidebar\Gadgets\ folder. This folder contains all the default gadgets from Microsoft.

Creating Simple RegEx Tester Gadget

Regular Expressions are complex but efficient technique for processing text. And the RegEx functions are available in Javascript. So I am to creating simple regex tester gadget using Javascript. You can find a simple RegEx Tester using Javascript here : http://www.regular-expressions.info/javascriptexample.html.

For creating a Gadget we require a XML Definition file, which contains the details about the Gadget File, Links to Icons, and Copyright information. Here is skeleton a XML Definition file.

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>RegExTester</name>
<namespace>dotnetthoughts</namespace>
<version>1.0.0.0</version>
<author name="dotnetthoughts">
<info url="http://dotnetthoughts.net" text="www.dotnetthoughts.net" />
<logo src="logo.png" />
</author>
<copyright>&#0169; 2010</copyright>
<description>For Testing Regular Expressions</description>
<icons>
<icon width="64" height="64" src="icon.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="RegExTester.html" />
<permissions>full</permissions>
<platform minPlatformVersion="0.3" />
</host>
</hosts>
</gadget>

And the Tags details are

name: Title of your gadget.
version: Version number of your gadget.
author: Your name or your company’s name.
info url: Web site address.
info text: Friendly name for your Web site.
logo src: Name of company’s logo image file.
copyright: Copyright notice.
description: Description of the gadget.
icon src: Name of icon image file for the gadget.
base src: Name of gadget’s main HTML file.

Gadget Details.

Gadget Details.

Save this file as Gadget.xml. Next we need to create the RegExTester.html, which is the main file, nothing but simple HTML file with some UI components.


<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/vbscript" src="message.vbs"></script>
<script type="text/javascript" src="regexcheck.js"></script>
<title>RegEx Tester</title>
</head>
<body>
<form>
<table border="1" cellpadding="1" cellspacing="5" bordercolor="red">
<tr><td><b><u>RegEx Tester</u></b></td></tr>
<tr><td><label>Regular Expression</label></td></tr>
<tr><td><textarea id="txtRegExp" cols="25" rows="4"></textarea></td></tr>
<tr><td><label>Subject String</label></td></tr>
<tr><td><textarea id="txtSubject" cols="25" rows="4"></textarea></td></tr>
<tr><td><button onclick="javascript:demoMatchClick();">Test Match</button>&nbsp;&nbsp;
<button onclick="javascript:demoShowMatchClick();">Show Match</button></td></tr> </table>
</form>
</body>
</html>

You may noticed that I have included a message.vbs file, it helps to display alert() boxes from Javascript. I don’t know why alert and prompt functions are not available in Gadgets. Also we don’t need to worry about cross platform compatibility issues in Gadgets, we can write anything supported by Microsoft Internet Explorer.

Here is the code of Message.vbs file.

sub alert(prompt)
MsgBox prompt, 48 , "RegEx Tester"
end sub

And here is the contents of regexcheck.js file.

function demoMatchClick() {
var regExCtrl = document.getElementById("txtRegExp");
var subjectCtrl = document.getElementById("txtSubject");
var re = new RegExp(regExCtrl.value);
if (subjectCtrl.value.match(re)) {
	alert("Successful match");
} else {
	alert("No match");
}
}
function demoShowMatchClick() {
var regExCtrl = document.getElementById("txtRegExp");
var subjectCtrl = document.getElementById("txtSubject");
var re = new RegExp(regExCtrl.value);
var m = re.exec(subjectCtrl.value);
if (m == null) {
	alert("No match");
} else {
	var s = "Match at position " + m.index + ":\n";
	for (i = 0; i < m.length; i++) {
		s = s + m[i] + "\n";
	}
	alert(s);
}
}

Also I added a CSS file for styling the components. Also to specify the Height and Width of the Gadget. In Windows Vista, we need to limit the size of the Gadget, because the Gadget can only place in the Sidebar, but in Windows 7 we can place the Gadget anywhere in the desktop. Also I have added icon.png and logo.png files, as specified in the XML definition file.
The current folder structure is like this.

Folder Structure

Folder Structure

Now using any compression tool, compress the files, and Rename it as RegExTester.Gadget. Double click on the Gadget file, Windows will ask for a confirmation.

Gadget install Confirmation

Gadget install Confirmation

Click Install. It will start the Gadget. Here is the screenshot of RegExTester gadget running on my Windows 7 machine.

RegExTester Running on Windows 7

RegExTester Running on Windows 7

This is an introduction only, I will try to post about Gadget API, Gadget Settings etc in the next post.

Happy Coding :)

Import Data from Excel using C# – Part 2

February 16th, 2010 Anuraj P 6 comments

In my web application, we used to import data from MS Excel file. Few days before one of the client representative posted an issue that he can’t import data from XLSX (MS Excel 2007 File Format) files. Previously we were using OLE DB provider to import data from Excel file (Checkout my previous post regarding How to Import / Export from C# : IMPORT / EXPORT DATA IN MS EXCEL USING C# ), but Microsoft worked on the Office 2007 file formats, and we are not able to connect to Excel using Microsoft.Jet.OLEDB. Yesterday I got a chance to work on this module, and thought of implementing XLSX support. After few searches I found a new provider from Microsoft to connect to Excel 2007 files, called Microsoft.ACE.OLEDB.12.0.

/// <summary>
/// Imports Data from Microsoft Excel File.
/// </summary>
/// <param name="FileName">Filename from which data need to import</param>
/// <returns>List of DataTables, based on the number of sheets</returns>
private List<DataTable> ImportExcel(string FileName)
{
    List<DataTable> _dataTables = new List<DataTable>();
    string _ConnectionString = string.Empty;
    string _Extension = Path.GetExtension(FileName);
    //Checking for the extentions, if XLS connect using Jet OleDB
    if (_Extension.Equals(".xls", StringComparison.CurrentCultureIgnoreCase))
    {
        _ConnectionString =
            "Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=Excel 8.0";
    }
    //Use ACE OleDb
    else if (_Extension.Equals(".xlsx", StringComparison.CurrentCultureIgnoreCase))
    {
        _ConnectionString =
            "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0";
    }

    DataTable dataTable = null;

    using (OleDbConnection oleDbConnection =
        new OleDbConnection(string.Format(_ConnectionString, FileName)))
    {
        oleDbConnection.Open();
        //Getting the meta data information.
        //This DataTable will return the details of Sheets in the Excel File.
        DataTable dbSchema = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables_Info, null);
        foreach (DataRow item in dbSchema.Rows)
        {
            //reading data from excel to Data Table
            using (OleDbCommand oleDbCommand = new OleDbCommand())
            {
                oleDbCommand.Connection = oleDbConnection;
                oleDbCommand.CommandText = string.Format("SELECT * FROM [{0}]",
                    item["TABLE_NAME"].ToString());
                using (OleDbDataAdapter oleDbDataAdapter = new OleDbDataAdapter())
                {
                    oleDbDataAdapter.SelectCommand = oleDbCommand;
                    dataTable = new DataTable(item["TABLE_NAME"].ToString());
                    oleDbDataAdapter.Fill(dataTable);
                    _dataTables.Add(dataTable);
                }
            }
        }
    }
    return _dataTables;
}

The connection string also supports HDR attribute, which decides, whether the Excel file first row is header or not. It can be either Yes or No. It can be used with both Excel 2003 and Excel 2007 files.

Update: You can download the Microsoft.ACE.OLEDB.12.0 provider from Microsoft : 2007 Office System Driver: Data Connectivity Components

System.InvalidOperationException – Cross-thread operation not valid

February 5th, 2010 Anuraj P 2 comments

System.InvalidOperationException – Cross-thread operation not valid: Control ‘xxxxx’ accessed from a thread other than the thread it was created on. Normally we get this exception when we try to modify some control property from another thread. This is because when a program executes the operating system will assign a thread for the creation of UI elements and for the changes of the UI. Only this thread has got the permission to change or control UI elements created. If you creates other threads with the help of Thread class from System.Threading namespace, doesn’t have enough privileges to change or control the UI elements of the Main thread. To resolve this issue, we need write delegates and need to invoke the methods from other threads using these delegates.

This sample code is doing some long operation in a separate thread and try to update the UI from the new thread.


private void Form1_Load(object sender, EventArgs e)
{
    this.threadStart = new ThreadStart(LongProcess);
    this.thread = new Thread(this.threadStart);
    this.thread.Start();
}
private void LongProcess()
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(100);
        //This will throw an exception like this
        //System.InvalidOperationException - Cross-thread operation not valid:
        //Control 'textBox1' accessed from a thread other than the thread it was created on.
        this.textBox1.Text = i.ToString();
    }
}

And here is the source code which will fix the issue with delegates and Control.Invoke method

private ThreadStart threadStart;
private Thread thread;
private delegate void UpdateTextDelegate(string text);
private void Form1_Load(object sender, EventArgs e)
{
    this.threadStart = new ThreadStart(LongProcess);
    this.thread = new Thread(this.threadStart);
    this.thread.Start();
}

private void LongProcess()
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(100);
        //This will resolve the cross thread invalid operation exception.
        this.UpdateText(i.ToString());
    }
}

private void UpdateText(string text)
{
    //Checks whether the called required to invoke the "Invoke" method.
    if (this.textBox1.InvokeRequired)
    {
        UpdateTextDelegate updateTextDelegate = new UpdateTextDelegate(UpdateText);
        //Calling the invoke method of the control with the parameter.
        this.textBox1.Invoke(updateTextDelegate, new object[] { text });
    }
    else
    {
        this.textBox1.Text = text;
    }
}

Thanks to Praveen for helping me out. Happing Coding :)

EDIT: In case WPF applications, we don’t have InvokeRequired property available for Controls. Instead we need to use Dispatcher.CheckAccess() method. We can rewrite the UpdateText method like the following

private void UpdateText(string text)
{
if (this.textbox1.Dispatcher.CheckAccess())
{
    this.textbox1.Content = text;
}
else
{
UpdateTextDelegate updateTextHandler = new UpdateTextDelegate(UpdateText);
this.textbox1.Dispatcher.Invoke(updateTextHandler, new object[] { text });
}
}

Thanks to Sivadas for his valueable comments.

Encrypting and Decrypting Configuration Sections

February 4th, 2010 Anuraj P No comments

Recently I got chance to work with security audit team for my web application, and one suggestion I got from them is to encrypt connection strings section in web.config. I thought it involves lot of coding changes, and I was not aware of ASP.Net utility which will help to encrypt and decrypt the connection strings or appsettings sections of the web application. There is no extra coding required to use this feature. You can encrypt /decrypt the connection strings / appsettings using the ASPNET_REGIIS utility. You can find this utility in your Framework folder, normally in C:\Windows\Microsoft.NET\Framework\[Version]. Or you can invoke this from Visual Studio Command Prompt.

Encrypt the connection string

aspnet_regiis -pe ConnectionString  –app "/docs"

where –pe is the parameter used to encrypt the section. Connection string is the section, if you want to encrypt AppSettings, use appsettings instead of Connectionstrings. And the –app parameter is used to specify the application (it must be virtual path and need to start with “/”), if –app parameter is not specified it will encrypt the Root web.config. If the application is in File System, you need to specify –pef and Physical location as the parameter.

aspnet_regiis -pef ConnectionString  –app "D:\MyWebApp"

Decrypt the connection string

It is almost same as Encryption, only difference is instead of –pe use –pd. And in the case of –pef use –pdf.

aspnet_regiis -pd ConnectionString  –app "/docs"

and

aspnet_regiis -pdf ConnectionString  –app "D:\MyWebApp"

You can also specify the Provider for Encryption too. Use –prov parameter for providing custom provider (You can create your own provider, for this you need to inherit from ProtectedConfigurationProvider class). By default it will be RsaProtectedConfigurationProvider.
Screenshots – Before and After encrypting the app settings.

Before Encryption

Before Encryption

After Encryption

After Encryption

Isolated Storage in C#

February 3rd, 2010 Anuraj P No comments

As I am working in a Windows Application, client asked about the Windows 7 and Windows Vista compatibility. As I was writing only managed code I was not worried about the compatibility and most of the time it was working fine. (I was using Windows Vista). Today evening one of my colleague was testing the application on his Windows 7 machine, the application was crashing :( After initial diagnostics I was able to find the solution, it was because of Tracing. I was using TextWriterTraceListener,from System.Diagnostics namespace, and the File was created in the application path.Because he installed the application in C:\Program Files\AppFolder, Windows was denied access to write the File. The easily solution was, Right Click on the Application, Select RUNAS option, select Administrator. The other solution was writing the Log File in some temporary location, and use it. Then I found some nice feature in .Net called Isolated Storage. It is helpful to Run your application by less privileged users. With these stores, you can read and write data that less trusted code cannot access and prevent the exposure of sensitive information that can be saved elsewhere on the file system. Data is stored in compartments that are isolated by the current user and by the assembly in which the code exists. Additionally, data can be isolated by domain. Roaming profiles can be used in conjunction with isolated storage so isolated stores will travel with the user’s profile.

We can access the Isolated Storage related classes from System.IO.IsolatedStorage namespace.

//Getting the User scoped Store corresponding to the calling codes assembly identity.
//IsolatedStorageFile class provides basic functionality to create files or folders.
IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForAssembly();
//Checking whether Directory Exists. Directory.Exists will not work. Also do some wildcard
//search like "dotnet*" or "dotnet?"
string[] directories = isolatedStorageFile.GetDirectoryNames("dotnetthoughts");
//Creating the directory if it is not exists.
if (directories.Length == 0)
{
    isolatedStorageFile.CreateDirectory("dotnetthoughts");
}
//IsolatedStorageFileStream encapsulates stream, used to create files
IsolatedStorageFileStream isolatedStorageFileStream =
    new IsolatedStorageFileStream(@"dotnetthoughts\\System.log",
        FileMode.OpenOrCreate, isolatedStorageFile);
//Writing the content to IsolatedStorage.
using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
{
    streamWriter.WriteLine("Hello Isolated Storage");
}
//Reading the contents from Isolated storage – If you try to read like this it will throw //exception.(Stream is not Readable)
using (StreamReader streamReader = new StreamReader(isolatedStorageFileStream))
{
    MessageBox.Show(streamReader.ReadToEnd());
}
isolatedStorageFileStream.Close();
isolatedStorageFile.Close();

There is some permission attributes too, which is used to grant code to access IsolatedStorage.


[IsolatedStorageFilePermission(SecurityAction.Demand)]
static class Program
{
//Code
}

The IsolatedStorage can be used in Silverlight assemblies too, which will helps to access local file system from Silverlight.