Friday, 6 February 2009

Getting Started with AJAX development and AJAX Control Toolkit

Developers who use Visual Studio 2008 know that AJAX already built into ASP.NET for .Net 3.5 Framework. All they need is to get AJAX Control Toolkit.

AJAX Control Toolkit .Net 3.5

How Do I: Get Started with ASP.NET AJAX? is an excellent video that helps to get started.

AJAX for .NET 2.0

If you are developing pure .Net 2.0 ASP.NET website or still using Visual Studio 2005 you need to get AJAX 1.0 and  AJAX Control Toolkit for .Net 2.0.

ASP.NET AJAX 1.0

ASP.NET 2.0 AJAX Templates for Visual Studio 2008

AJAX Control Toolkit for .NET Framework 2.0, ASP.NET AJAX 1.0

AJAX Tutorials and Documentation

AJAX Website has extensive number of Tutorials and Control Toolkit has a sample website that will be very helpful to make learning curve shorter.

ASP.NET AJAX Videos

ASP.NET AJAX Documentation

AJAX Control Toolkit Tutorials (C#)

ASP.NET Learning Centre

Deployment of AJAX enabled websites

Once development is finished and project need to be deployed to testing or production servers, install ASP.NET AJAX 1.0 on the server if you are deploying ASP.NET 2.0 website. ASP.NET 3.5 website will require only .NET 3.5 runtime installed on the server. There is no need to install AJAX toolkit as long as toolkit DLL is distributed in bin folder.

Wednesday, 28 January 2009

ASP.NET Access DB write problem

Recently I was working on simple ASP.NET website that had to update Access Database. Everything was fine during development when I was using ASP.NET Development Server created by Visual Studio. Later when I connected with Internet browser to http://localhost/mywebsite/Default.aspx I started getting two kind of unhandled exceptions on Database insert and update.

Microsoft JET Database Engine error '80004005'

The Microsoft Jet database engine cannot open the file 'C:\DB\YourDatabase.mdb'. It is already opened exclusively by another user, or you need permission to view its data.

or this one

Microsoft JET Database Engine error '80004005'

Operation must use an updateable query.

After looking on the internet I found a couple of links that shed some light on this problem.

How Do I Fix ASP 80004005 errors? - Imar.Spaanjaars.Com

An unhandled exception may occur when you try to connect to an Access database from an ASP.NET worker process.

I tried to fix a problem by following instructions on these pages, unfortunately adding permission for IUSR_MyComputerName system user to access DB folder did not make a difference. The quick and easy (and NOT RECOMMENDED for production installation) solution is to add Everyone to access to DB folder and write to database. I want to repeat that this is not a good solution for security reasons, my preference is to try to change an account under which IIS service is running. I will post my solution later once I get it working.

References

How to configure file sharing in Windows XP

Friday, 19 December 2008

Download Windows Updates for offline install

Recently I performed a complete reinstall of my desktop computer and now require to download all windows updates again. With only 1Gb of available download and upload a month it will be easy to quickly use up all of it if with these updates. For these who want to save distributable copies of patches Microsoft provides two web sites to download updates from.

It is possible to find windows updates for XP, Vista and any other windows flavour, just search for KB# like (KB956391) which is shown in Automatic Updates window.

WindowsUpdates

Saturday, 1 November 2008

Tip: Create simple "Hello World" Desktop Sidebar Panel Plug-In

In this post I would like to cover step by step instructions on how to create a Plug-in for Windows Desktop Sidebar using a Desktop Sidebar SDK and C# .Net 2.0.

Prerequisites

Getting Started

Download and install Windows Desktop Sidebar by following a link. After installation is done go to installed sidebar directory, by default it will be "C:\Program Files\Desktop Sidebar". Find and unzip dssdk.zip file into "C:\Program Files\Desktop Sidebar\dssdk" or any other location of your choice.

Simple Hello World Sidebar Plug-In

Now it is time to start on creating our simple "Hello World" Desktop Plug-in. It will have a "Hello World!" button on the panel and by clicking on it it will display a "Hello There!" label.

Start a Visual Studio IDE and select "Create Project ...". Select C# Windows Forms Control Library or Windows Control Library and name it HelloWorldSidebar. In Visual Studio 2008 make sure that .Net Framework 2.0 is selected. Click OK.

NewProject

New Solution and Project will be created. Set a reference to Desktop Sidebar SDK dsidebarpia.dll.

SetReference

Rename UserControl1.cs as HelloWorldPanel.cs. This will be a UI of the panel displayed in the sidebar.

solution

Double Click on HelloWorldPanel.cs and add label and button as shown. Lets name label and button as lblHello, btnHello. This will be our UI of the sidebar Plug-In.

PanelUI

Double Click "Hello World!" button and add the following code.

private void btnHello_Click(object sender, EventArgs e) { lblHello.Text = "Hello There!"; }

Now starts something more interesting. Add "using DesktopSidebar;" at the top of the HelloWorldPanel.cs file. In order for a panel to appear in the sidebar it need to inherit from IPanel, IPanelWindow and IPanelProperties interfaces. Add them to HelloWorlPanel class declaration as shown. We will implement these interfaces shortly.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using DesktopSidebar; namespace HelloWorldSidebar { public partial class HelloWorldPanel : UserControl, IPanel, IPanelWindow, IPanelProperties { public HelloWorldPanel() { // Comment this out to enable panel refresh in the sidebar // InitializeComponent(); } private void btnHello_Click(object sender, EventArgs e) { lblHello.Text = "Hello There!"; } } }

Moment of the truth! Make sure that InitializeComponent(); in HelloWorlPanel() constructor is commented. It took me one day to workout why sidebar was not repainting.

Implementing Interfaces

To create Interface methods and properties use a shortcut provided by Visual Studio to Implement Interfaces. Use Implement Interface entry to auto-create them.

ImplementInterfaces

IPanel Members

Here we need to use 3 Win32 API functions defined in Win32API Declarations region - SendMessage, SetParent, GetParent.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using DesktopSidebar; namespace HelloWorldSidebar { public partial class HelloWorldPanel : UserControl, IPanel, IPanelWindow, IPanelProperties { .... #region IPanel Members protected Sidebar sidebar; protected IPanelParent panelParent; protected IPanelConfig panelConfig; protected int panelCookie; protected int parentWnd = -1; #region Win32API Declarations public const int WM_CLICK = 0x00F5; public const int WM_LBUTTONDOWN = 0x0201; public const int WM_LBUTTONUP = 0x0202; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "SetParent")] static extern int SetParent(int hwndChild, int hwndNewParent); [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] public static extern IntPtr GetParent(IntPtr hWnd); #endregion Win32API Declarations public void Close() { //throw new NotImplementedException(); } public void Create(int hwndParent, Sidebar Sidebar, IPanelParent parent, IPanelConfig config, ICanvas canvas, IXmlNode configRoot, IXmlNode panelConfig, IXmlNode settingsRoot, IXmlNode panelSettings, int cookie) { panelParent = parent; panelCookie = cookie; this.panelConfig = config; parentWnd = hwndParent; SetParent((int)Handle, hwndParent); panelParent.SetCaption(panelCookie, "Hello World Sidebar!"); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); InitializeComponent(); Application.DoEvents(); } public void Save(IXmlBuilder panelItem, IXmlBuilder settingsRoot) { //throw new NotImplementedException(); } public bool Tick(bool minute) { return false; } #endregion IPanel Members .... }

IPanel Window Members

#region IPanelWindow Members public int GetFitHeight(int width) { return Height; } protected delegate System.IntPtr DelegateGetHwnd(); public IntPtr GetHwnd() { if (this.InvokeRequired) return (System.IntPtr)this.Invoke(new DelegateGetHwnd(GetHwnd)); return Handle; } #endregion IPanelWindow Members

IPanel Properties Members

#region IPanelProperties Members public void ShowProperties(int hwnd) { //throw new NotImplementedException(); } #endregion IPanelProperties Members

Plugin class

In order to attach our Panel to Sidebar we need to create a Plugin class that inherits IPlugin and IPanelCreator interfaces. Add a C# class file to project and name it plugin.cs. Also you need to find and add a bmp image file that can be used as panel.bmp to display as an icon in the panel. Add panel.bmp file as existing Item to a project and set BuildAction property to "Embedded Resource".

using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using DesktopSidebar; namespace HelloWorldSidebar { public class Plugin : IPlugin, IPanelCreator { public Plugin() { } #region IPlugin Members public void Load(out string author, out string authorEMail, out string description, out string website, int sidebarBuild, Sidebar Sidebar, IXmlNode pluginConfig, int pluginCookie) { AppDomain.CurrentDomain.AppendPrivatePath(@"plugins\HelloWorldSidebar"); author = "My Company Name"; authorEMail = "mail@mycompany.com"; description = "Hello World Sidebar"; website = "www.mycompany.com"; Bitmap bmp = new Bitmap(GetType(), "panel.bmp"); ImageList imageList = new ImageList(); imageList.Images.Add(bmp, Color.FromArgb(0, 255, 0)); Sidebar.RegisterPanel( "HelloWorldSidebar", "Hello World Sidebar", "Hello World Sidebar Plugin", (int)imageList.Handle, "0", "Hello World Sidebar", "0", "", "", pluginCookie); imageList.Dispose(); bmp.Dispose(); } public void OnPluginLoaded(string plugin) { //throw new NotImplementedException(); } public void Unload() { //throw new NotImplementedException(); } #endregion IPlugin Members #region IPanelCreator Members public void CreatePanel(ref IPanel panel, string panelClass) { if (panelClass == "HelloWorldSidebar") { panel = new HelloWorldPanel(); } } #endregion IPanelCreator Members } }

HelloWorldSidebar.dsplugin file

Desktop Sidebar knows about it's plug-ins from *.dsplugin files. Add new xml file to a project and name it HelloWorldSidebar.dsplugin.

<?xml version="1.0" encoding="utf-8" ?> <plugin progid="HelloWorldSidebar.Plugin" compatible="61" > <defaults> <panel name="HelloWorldSidebar" > <item name="decorated" value="1"/> <item name="frequency" value="1"/> </panel> </defaults> </plugin>

Project Properties

Our Sidebar plug-in is almost ready to be built and used. Lets edit Project Properties to set where our sidebar should be copied after build and what exe to run on debug.

Project Post Build Events

Open Project Properties, Build Events and Edit "Post Build Events". Copy the following lines.

mkdir "C:\Program Files\Desktop Sidebar\plugins" mkdir "C:\Program Files\Desktop Sidebar\plugins\$(ProjectName)" copy "$(TargetDir)*.*" "C:\Program Files\Desktop Sidebar\plugins\$(ProjectName)" copy "$(ProjectDir)*.dsplugin" "C:\Program Files\Desktop Sidebar\plugins\$(ProjectName)"

Project Build and Debug

In Project Debug select Start external Program and set path to sidebar executable.

C:\Program Files\Desktop Sidebar\dsidebar.exe

In Project Build tick Register for COM Interop box. This change will not have any affect if we do not set ComVisible property to true in AssemblyInfo.cs file.

[assembly: ComVisible(true)]

Running Hello World Sidebar Plug-in

Lets start our sidebar plug-in by hitting F5. If everything was done correctly sidebar will appear on the right side of the screen. Our Panel is not visible yet and we need to add it to a panel. Right mouse click on the Sidebar and select "Add Panel ..." from menu. Select "Hello World Sidebar" from the list.

AddNewPanel

And here it is in the list.

HelloWorldSidebar