Search This Blog

Saturday 17 September 2011

How to Sync schema changed database using sync framework?


I was working on azure database synchronization for the last month and successfully completed the task. In my case both databases, source and target are in the azure. We can also done the sync from azure to local also. Below are the codes for using sync two azure database.
Step by Step process of sync databases using sync framework :
1. Create both source db and target db connection strings
2. Create DbSyncScopeDescription object ‘myscope’ for describing our scope.
3. Add tables to the ‘myscope’ that we need to sync
4. Do the provisioning process for both source db and target db.
5. Set memory allocation to the database providers
6. Set application transaction size on destination provider.
7. Create object for class SyncOrchestrator and call Synchronize() method.
public static void Setup(string sqlSourceConnectionString, string sqlTargetConnectionString, 
string scopeName, int scopeid, Scope ScopeDetails)
 {
 try
 {
 SqlConnection sqlServerConn = new SqlConnection(sqlSourceConnectionString);
 SqlConnection sqlAzureConn = new SqlConnection(sqlTargetConnectionString);
 DbSyncScopeDescription myScope = new DbSyncScopeDescription(scopeName);
string connectionstring = ConfigurationSettings.AppSettings["ConnectionString"];
 SqlDataReader myDataReader = null;
 SqlConnection conn = new SqlConnection(connectionstring);
//Adding tables that we need to sync from the source db
 SqlCommand cmd = new SqlCommand("Select TableName from scheduler_tables where scopeid =" + scopeid, 
conn);
 conn.Open();
 myDataReader = cmd.ExecuteReader();
while (myDataReader.Read())
 {
 DbSyncTableDescription TestSchema1 = 
SqlSyncDescriptionBuilder.GetDescriptionForTable(Convert.ToString(myDataReader["TableName"]), 
sqlServerConn);
 // Add the tables from above to the scope
 myScope.Tables.Add(TestSchema1);
 }
// Setup SQL Server for sync
 SqlSyncScopeProvisioning sqlServerProv = new SqlSyncScopeProvisioning(sqlServerConn, myScope);
 sqlServerProv.CommandTimeout = 60 * 30;
 if (!sqlServerProv.ScopeExists(scopeName))
 {
 // Apply the scope provisioning.
 sqlServerProv.Apply();
 }
// Setup SQL Azure for sync
 SqlSyncScopeProvisioning sqlAzureProv = new SqlSyncScopeProvisioning(sqlAzureConn, myScope);
 sqlAzureProv.CommandTimeout = 60 * 30;
 if (!sqlAzureProv.ScopeExists(scopeName))
 {
 sqlAzureProv.Apply();
 }
 sqlAzureConn.Close();
 sqlServerConn.Close();
Sync(sqlSourceConnectionString, sqlTargetConnectionString, ScopeDetails, instanceID);
 }
 catch (Exception ex)
 {
 throw;
 }
 }
public static void Sync(string sqlSourceConnectionString, string sqlTargetConnectionString, 
Scope ScopeDetails)
 {
 try
 {
 SqlConnection sqlServerConn = new SqlConnection(sqlSourceConnectionString);
 SqlConnection sqlAzureConn = new SqlConnection(sqlTargetConnectionString);
SqlSyncProvider RemoteProvider = new SqlSyncProvider(ScopeDetails.ScopeName, sqlAzureConn);
 SqlSyncProvider LocalProvider = new SqlSyncProvider(ScopeDetails.ScopeName, sqlServerConn);
//Set memory allocation to the database providers
 RemoteProvider.MemoryDataCacheSize = MemorySize;
 LocalProvider.MemoryDataCacheSize = MemorySize;
//Set application transaction size on destination provider.
 RemoteProvider.ApplicationTransactionSize = BatchSize;
//Count transactions
 RemoteProvider.ChangesApplied += new EventHandler(RemoteProvider_ChangesApplied);
SyncOrchestrator orch = new SyncOrchestrator();
 orch.RemoteProvider = RemoteProvider;
 orch.LocalProvider = LocalProvider;
 orch.Direction = SyncDirectionOrder.Upload;
String syncdetails;
 syncdetails = ShowStatistics(orch.Synchronize());
 sqlAzureConn.Close();
 sqlServerConn.Close();
}
 catch (Exception ex)
 {
 throw;
 }
 }
public static string ShowStatistics(SyncOperationStatistics syncStats)
 {
 string message;
 syncStartTime = syncStats.SyncStartTime.ToString();
 message = "\tSync Start Time :" + syncStats.SyncStartTime.ToString();
 //Console.WriteLine(message);
 syncEndTime = syncStats.SyncEndTime.ToString();
 message = message + "\tSync End Time :" + syncStats.SyncEndTime.ToString();
 //Console.WriteLine(message);
 message = message + "\tUpload Changes Applied :" + syncStats.UploadChangesApplied.ToString();
 //Console.WriteLine(message);
 message = message + "\tUpload Changes Failed :" + syncStats.UploadChangesFailed.ToString();
 //Console.WriteLine(message);
 message = message + "\tUpload Changes Total :" + syncStats.UploadChangesTotal.ToString();
 //Console.WriteLine(message);
 message = message + "\tDownload Changes Applied :" + syncStats.DownloadChangesApplied.ToString();
 //Console.WriteLine(message);
 message = message + "\tDownload Changes Failed :" + syncStats.DownloadChangesFailed.ToString();
 //Console.WriteLine(message);
 message = message + "\tDownload Changes Total :" + syncStats.DownloadChangesTotal.ToString();
 //Console.WriteLine(message);
return message;
 }
The above codes are working fine until any schema changes occurred in the source database. If we made any schema changes on the source sync will be failed.
In my experience, I have added a new column in the source db called ‘isActive’ and got error once I trying to sync again “invalid column name isActive’”.
The cause of the issue is when we sync first time, will created so many tables, stored procedures and triggers by sync framework to identify that which areas to be taken sync in future or which areas having changes after the previous sync.
So we need to clear all these data related to sync, then only it will take any schema changes in the source db. For delete this records Microsoft providing a class SqlSyncScopeDeprovisioning and method DeprovisionStore() for removing all these data. So if we have any schema changes in the source database, we need to create a object of the class and call this method before applying the provision. Below are the codes to de provision the entire db,
SqlSyncScopeDeprovisioning deprovisioningvar = new SqlSyncScopeDeprovisioning(sqlServerConn);
deprovisioningvar.DeprovisionStore();
Then it is working fine ..! The problem is that it will clear all the data regarding the previous sync so it will take long time to sync first time, for the second time onwards there is no need to do the deprovison until any new schema changes occurred.

Compress and extract file using Gzipstream


I have faced situation for downloading large blob files from azure server to local folder. It was easy todownload the file from azure server. But if file has more than 2 GB (means larger size) it will got error in the middle of the downloading. When I was facing the issue, I was search on google and not found feasible solution soon that’s why I posted this compress and decompress codes here..
using System.IO.Compression;

Compress files ….
public static void Compress(FileInfo fi)
        {
            // Get the stream of the source file.
            using (FileStream inFile = fi.OpenRead())
            {
                // Prevent compressing hidden and
                // already compressed files.
                if ((File.GetAttributes(fi.FullName)
                    & FileAttributes.Hidden)
                    != FileAttributes.Hidden & fi.Extension != “.gz”)
                {
                    ///**
                    //string[] filesplits = fi.FullName.Split(‘.’);
                    // Create the compressed file.
                    using (FileStream outFile =
                                File.Create(fi.FullName + “.gz”))
                    {
                        using (GZipStream Compress =
                            new GZipStream(outFile,
                            CompressionMode.Compress))
                        {
                            // Copy the source file into
                            // the compression stream.
                            inFile.CopyTo(Compress);
                            Console.WriteLine(“Compressed {0} from {1} to {2} bytes.”,
                                fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                        }
                    }
                }
            }
        }


Decompress compressed file..
public void Decompress(FileInfo fi)
        {
            // Get the stream of the source file.
            using (FileStream inFile = fi.OpenRead())
            {
                // Get original file extension, for example
                // “doc” from report.doc.gz.
                string origName = curFile.Remove(curFile.Length -
                        fi.Extension.Length);
                //Create the decompressed file.
                using (FileStream outFile = File.Create(origName))
                {
                    using (GZipStream Decompress = new GZipStream(inFile,
                            CompressionMode.Decompress))
                    {
                        // Copy the decompression stream
                        // into the output file.
                        Decompress.CopyTo(outFile);
                        Console.WriteLine(“Decompressed: {0}”, fi.Name);
                    }
                }
            }
        }

How can Read and Write Text Files with ASP.NET?


In most of the cases, asp.net developer needs to work with read and write text files from the local folder. By using this function, developer can write and save any errors occurred in the application to a txt files and can refer later. Also having so many chances for this function in various domain.
This is a simple explanation of reading and writing text files in ASP.NET 2.0 using theStreamReader and StreamWriter classes.
To read a text file using the System.IO.StreamReader class into a TextBox control use the following code:
System.IO.StreamReader StreamReader1 =
new System.IO.StreamReader(Server.MapPath(“test.txt”));
TextBox2.Text = StreamReader1.ReadToEnd();
StreamReader1.Close();
If the file does not exist you will get an error. You can check to see if the file exists using this code:
if (System.IO.File.Exists(Server.MapPath(“test.txt”)))
To write the contents of a TextBox control to a text file using the System.IO.StreamWriter class use the following code:
System.IO.StreamWriter StreamWriter1 =
new System.IO.StreamWriter(Server.MapPath(“test.txt”));
StreamWriter1.WriteLine(TextBox1.Text);
StreamWriter1.Close();
In the above example the StreamWriter class will create the text file if it does not exist and over write the file if it does exist. Line breaks in a TextBox control that uses multiline mode will show up in the text file.
Inserting “\r\n” will create a line break in the text file. Adding line breaks from code can be done using this code:
StreamWriter1.WriteLine(“Some text on line1.\r\nSome text on line2.”);
The dowload contains a web page containing two TextBox controls. Edit the TextBox on top and click the save button. A text file will be created using the text in the top TextBox and saved in the same virtual directory as the web page. The new text file is then loaded into the bottom TextBox to show that changes were saved.
This simple example has demonstrated a couple of the more frequent uses for the StreamReader and StreamWriter classes. They can be used with all kinds of text files including XML, web pages, classes (.cs or .vb), and many more.

How to sync large size database with sync framework


By using sync framework 2.1 we can easily sync databases frequently by scheduling sync with some interval. In one of our project we have to give chance for client to schedule sync frequently. We have implemented the functionalities using sync framework 2.1 with ASP.Net mvc application. You can go through the main codes for sync here.
It was working fine until we are testing with large size db (greater than 10 GB). When we are testing with large size db, we got error in the middle of sync process.
The error is  “There is no enough space for the disk”. Then we are increased the size of the target db to 20 GB (source db 10GB) but got same error. We are search on the google and cannot found enough support for the issue. We are going behind the issue and after some days we have found the root cause of the issue. It was not related to sync framework. When sync process is running, a log file will be writing as backend process to the location “C:\Resources\temp\7aad4070ce51495c82cde6b1d410aa65.WorkerRole1\RoleTemp” of Virtual Machine in the worker role (WaHostBootstrapper). The size of this log file will be increasing continuously and there is some limitation for the size of the file (normally 60 mb). Obviously it will take long time to sync large db and log file size increased and crashed once the max size exceeded. At last we have found the solution and now our application can sync large db without any error. The solution is given below.
1.    We need to extend the max size of the log file. We can achieve it by following code in the “ServiceDefinition.csdef”
<LocalResources>
      <LocalStorage name=”localStoreOne” sizeInMB=”20480″ cleanOnRoleRecycle=”true” />
    </LocalResources>
   Name ( localStoreOne) : indicates your local storage name
    sizeInMB : indicates the maximum size of the log file you want to give.
    cleanOnRoleRecycle : It will delete and recreated log file for each workerrole when it is        set to true
2.    In the “OnStart()” method in the workerrole we need to map the temp folder by using following code.
string customTempLocalResourcePath =
       RoleEnvironment.GetLocalResource(“localStoreOne”).RootPath;
       Environment.SetEnvironmentVariable(“TMP”, customTempLocalResourcePath);
       Environment.SetEnvironmentVariable(“TEMP”, customTempLocalResourcePath);
Then we can see that log file is archived in the middle of sync with some size, and can hold up to the size that we mentioned in the ServiceDefenition file. It is better to  cleanOnRoleRecycle is set to true, then it will automatically deleted the log files once the worker role restart and recreated again.

Very simple JQuery News Ticker created within three steps.


In most of the website we can see that latest news and updates are shown on right or left panel. We can implemented vertical newsletter using jquery with three steps only. By using this vertical news ticker we can shown our company’s latest news, ads, announcements, events and updates with more attractive and wonderful animations.
Step by Step process to create vertical newsletter using jquery
1. Go through this link  and save .js files as jquery.js
2. Go through this link  and save .js file as jquery.vticker-min.js.
3. Create a html page and copy paste below codes to html page and save as index.html.
 
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/><title>vTicker</title>
<metaname="description"content=" "/><metaname="keywords"content=" "/>
<styletype="text/css"media="all">body, html
{padding: 0;margin: 0;}
body
{background: #00000;}
#news-container
{width: 200px;margin: auto;margin-top: 30px;
border-bottom: 2pxsolid#333333;border-top: 2pxsolid#333333;}
#news-containerullidiv{
border-bottom: 1pxsolid#aaaaaa;padding: 2px;background: #ffffff;
}
</style><scripttype="text/javascript"src="jquery.js">
</script><scripttype="text/javascript"src="jquery.vticker-min.js">
</script><scripttype="text/javascript">
$(function() {$('#news-container').vTicker({
speed: 900,
pause: 3000,
showItems: 1,
animation:'fade',
mousePause:true,
height: 0,
direction:'down'
});
});
</script>
</head>
<body>
<divid="news-container"><ul><li><div>
1) Lorem ipsum dolor sit amet, consectetur adipiscing elit. more info
</div></li><li><div>
2) Lorem ipsum dolor sit amet, consectetur adipiscing elit. more info
</div></li><li><div>
3) Lorem ipsum dolor sit amet more info more info more info more info
</div></li><li><div>
4) tuvian.com jquery vticker more info more info more info more info more info
</div></li></ul></div>
</body>
</html>
News ticker is ready..! Please run the index.html page and you can see the nes ticker with content scrolling to down, with some time interval, speed and fade animation. You can also customize your news by adjusting some values in the html page.
speed: 900,
pause: 3000,
showItems: 1,
animation: 'fade',
mousePause: true,
height: 0,
direction: 'down'
Please change the above code portion in the html page and enjoy the changes seen

Thickbox(3.1) not working with latest jQuery?


Issue while using Thickbox(3.1) jquery
We have implemented thick box jquery image popup in one of our products and it is not working properly. But the refered site shown that it is working fine. We have debugged the issue and found that the issue happening once the jquery trying to get all images with same rel attribute. In the refered site it is achieved by the code
       TB_TempArray = $("a[@rel="+imageGroup+"]").get();
 
Here we are getting error and was not able to get all images with same attribute. After the long checking we have found that, the issue is due to the latest jquery files that we used. In latest jquery @ is not valid, so we have removed the @ from above code and it is working fine now. 
How to get all images with same rel attribute in JQuery
    
      TB_TempArray = $("a[rel="+imageGroup+"]").get();
 
We are hoping that someone may have great help fron this post, because we were spending so many time for resolving the issue.

How to send mail using Gmail in ASP.Net with Godaddy Server?


Cannot send email in ASP.Net through GoDaddy Servers?
In ASP.Net we can sennd mail to anyone using gmail smtp server. We have created codes for sending mail using gmail credentials and it is working fine in local. But when we uploaded to the server we are unable to send mail using the options. The thing is that we are using GoDaddy Server as hosting server and it is not supported the gmail smtp server to send mail.
How to Send mail in ASP.Net with GoDaddy Server
Inorder to send mail using ASP.Net we got a support from godaddy department and now it is working fine. Following are the codes for sending mail in ASP.Net with GoDaddy Server:
using System.Web.Mail;

public static void sendEmail(EmailDetails objEmail)
        {
            try
            {
                string SERVER = ConfigurationSettings.AppSettings["MailServer"].ToString();

                MailMessage oMail = new System.Web.Mail.MailMessage();
                oMail.From = objEmail.From;
                oMail.To = objEmail.To;
                oMail.Cc = ConfigurationSettings.AppSettings["AdminEmailID"].ToString();
                oMail.Subject = objEmail.Subject;
                oMail.BodyFormat = MailFormat.Html;   // enumeration
                oMail.Priority = MailPriority.High;   // enumeration
                oMail.Body = objEmail.Message;
                SmtpMail.SmtpServer = SERVER;
                SmtpMail.Send(oMail);
                oMail = null; // free up resources
            }
            catch (Exception ex)
            {
                throw;
            }
        }
Here we have a object ‘objEmail’ which holds the mail details such as from address, to address, subject etc. We have to use System.Web.Mail class for send mail. Here we are taking server details from web.config as given below.
  <add key="MailServer" value="mail.gmail.com" />

When we are running in local system the above code is working fine, but when we uploaded to goDaddy server send mail is not working. Then we have to change mail server details in web.config to following one.
<add key="MailServer" value="relay-hosting.secureserver.net" />

How to create a news scroller using HTML marquee.


Very simple News Scroller using HTML
In most of the website we can see that there is a portion for updates from the company. This updates can be shown by javscript,jquery,ajax etc technologies and it should be some effort also we have to include some pages for this.
For eg if we are implemented javscript newsticker the user’s browser must enable javascript, otherwise nothing going to happen. So the better method is if we can create a simple news ticker by using html elements only, it will be more faster and reliable in all browsers.
Following are the very simple and attractive vertical news ticker using HTML elements only. (Without using jquery,js,ajax..) So it should be work in all browsers even in the javascript disabled mode. We can give more attractive color and style for the news ticker.
Simple HTML code for showing news updates.
<div style="width: 180px; text-align: center; margin-top: 30px;
margin-bottom: 2px;
        font-weight: bold;">
        Announcements</div>
    <div id="news-container">
        <marquee bgcolor="#ffffff" scrollamount="1" height="80"
direction="up" loop="true"
            width="95%">
        We offers shopping cart <span style="color: blue;">
domain hosting free</span>
for limitted customers.
        <br /><br />
        You can choose your own style,color and domain
for your shopping site.
        <br /><br />
        Supershope has largest number of viewers in the world.
<span style="color: blue;">
You can sell your products here.</span><br />
        <br />
        <span style="color: blue;">Gift Paintings on Sale..!</span>
There are thousands of
paintings available in supershope.
        Please contact us to buy paintings for affordable price.
        <br /><br />
        The Shopping cart product with <span style="color: blue;">
'supershope.com' domain also
            avaliable </span>for first customer with special package.
    </marquee>
    </div>
Where is simple HTML news ticker implemented
You can see the implemented HTML news ticker in the left hand side of the websit supershopeused as Announcements section

Pagination Stored Procedure in MySQL


Simple steps to create pagination store procedure in MySQL
We have already posted how to do pagination in sql server in last post. But in the case of MySQL as database we need to create procedure some little bit different from SQL. MySQL provides a technique to fetch some small amount of data by giving starting row and end row using keyword LIMIT.
How to select paging data from MySQL using Limit Keyword
Limit keyword is used to fetch paging data from mySQL. We can send parameter as firstRow and lastRow that we need to fetch from the table.
Eg : Select * from items Limit 0,10   >> return firt 10 records
     Select * from items Limit 11,10   >> return 10 records starts from 11
But the the problem is that in stored procedure if we send fromRow and lastRow as parameter, we are unable to set this parameter with Limit keyword, because this facility is not supported by mySQL.
ie:  Select * from items Limit 0,10 >> it will work
     Select * from items Limit firstRow,lastRow >> It will not work
Dynamic query in pagination stored procedure in mySQL
For resolving the issue, we need to create dynamic stored procedure and execute the statement. Dynamic query is nothing but we are dynamically creating query, means set a query to variable and run this variable using EXECUTE keyword.
Following Pagination stored procedure accept firstRow and lastRow parameter and create a dynamic query and executed. It will send only the records between firtRow and lastRow. In order to maintain the pagination in development we need to get total number of records, here it is achieving by the query select found_rows().

DELIMITER $$

DROP PROCEDURE IF EXISTS `myDB`.`usp_getItems` $$
CREATE PROCEDURE ` myDB `.`usp_getItems` (
firstrow int,
lastrow int
)
BEGIN

set @sql = concat(
'SELECT items.ID,items.Name,items.Description,items.Overview,
items.Price,items.Image,items.HasOffer,'
, 'items.OfferPrice,items.OfferDescription,
items.ItemCode,category.ID as CategoryID,'
, ' category.Name as category,subcategory.ID as SubCategoryID, '
, 'subcategory.Name as subcategory, items.IsActive,
items.ReleaseDate, items.Specefications '
, 'FROM items INNER JOIN subcategory ON '
, 'items.SubCategoryID = subcategory.ID
INNER JOIN category ON subcategory.CategoryID = category.ID '
, ' ORDER BY Name LIMIT '
, firstrow , ',' , lastrow
);

/*select @sql; */

PREPARE STMT FROM @sql;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;

select found_rows();

END $$

DELIMITER ;

Pagination Stored Procedure in SQL


When listing large amount of data from database, we have to face performance issue in ASP.net pages. There is a default paging mechanism available for some listing controls like Gridview, Listview etc. But all of them have to get total amount of data for manipulation, and from that data they are listing small amount of data using paging mechanism.
 That means, if there are 1 crore rows of data in the table, first of all we need to query out this all records and set to listing control. So it will take very long time to query out this amount of data from the table. 
Better method of pagination in SQL 
So the better mechanism for pagination is, we need to query only small amount of data that we need to display to the user at a time. In order to fetch this function, we have to create a store procedure in SQL with start and end row as parameter. Then If we pass 21 and 30 to the following procedure it will return only 21 to 30 (10 records) and total number of records. So it will be very fast mechanism for pagination.
Pagination Stored Procedure in SQL

CREATE PROCEDURE [dbo].[scheduler_view_syncjobs_paging]
@fromRow INT,
@toRow INT
AS
BEGIN

WITH SyncJobs AS
(
      SELECT coalesce(instance.Schedule_Time,
scope.ScheduleTime,getdate()) as ScheduleTime
    ,scope.ScopeName
    ,instance.Status
      ,instance.Schedule_Time as starttedTime
      ,logs.logDetails
      ,ROW_NUMBER() OVER (ORDER BY scope.ScopeID DESC) AS 'RowNumber'
      FROM scheduler_scope scope
      LEFT JOIN scheduler_SyncInstance instance on
instance.ScopeId=scope.Scopeid
      LEFT JOIN scheduler_logs logs on
logs.InstanceID=instance.InstanceId
)
SELECT Count(*) as TotalCount
FROM SyncJobs;

WITH SyncJobs AS
(
      SELECT coalesce(instance.Schedule_Time,
scope.ScheduleTime,getdate()) as ScheduleTime
    ,scope.ScopeName
    ,instance.Status
      ,instance.Schedule_Time as starttedTime
      ,logs.logDetails
      ,ROW_NUMBER() OVER (ORDER BY scope.ScopeID DESC) AS 'RowNumber'
      FROM scheduler_scope scope
      LEFT JOIN scheduler_SyncInstance instance on
instance.ScopeId=scope.Scopeid
      LEFT JOIN scheduler_logs logs on
logs.InstanceID=instance.InstanceId
)
SELECT *
FROM SyncJobs
WHERE RowNumber BETWEEN @fromRow AND @toRow;

END

GO

How to delete large amount of rows from table in SQL


In some scenario we have to delete large amount of rows from sql table and it will going to timeout if the table has very large amount of rows (Some tables in the database has more than crore rows). In this scenario we need to delete some small amount of records and from the table and continue the process until all records in the table deleted. 
Query for recursive deletion from the table in SQL  
Below codes delete 50000 rows recursively untill all records int the table deleted. So it never meets the timeout exception and will complete execution faster than normal query 
WHILE exists (
SELECT * FROM myTable WHERE name like ‘%ab%’
 )
DELETE TOP (50000) scanned_cont_dtls WHERE name like ‘%ab%’;

How to create a simple Ajax Collapsible Panel Extender in asp.net


The collapsiblePanel is used to collapse and expand any web page content or controls inside asp.net panel control. Panel control will expand and collapse by using label control or linkbutton control. For clean collapse and expand use Label Control to target collapse and expand panel control.
Properties of CollapsiblePanelExtender
TargetControlID – the Panel to operate expand and collapse. Use Panel control as TargetControlID
Collapsed – It specifies that the object should initially be collapsed or expanded.
AutoCollapse – when it is property is True to automatically collapse when the mouse is moved off the panel. It is better to keep false for clean collapse
AutoExpand – when it is property is True to automatically expand when the mouse is moved over the panel. It is better to keep false for clean collapse
ScrollContents – True to add a scrollbar if the contents are larger than the panel itself. False to just clip the contents.
ExpandControlID/CollapseControlID – The controls that will expand or collapse the panel on a click, respectively. If these values are the same, the panel will automatically toggle its state on each click. ExpandControlID or CollapseControl ID use label control
CollapsedImage – It views the image assigned by image path of the ImageControlID when the panel is Collapsed
ExpandedImage – It views the image assigned by image path of the ImageControlID when the panel is expanded
ExpandDirection – It can be “Vertical” or “Horizontal” to determine whether the panel expands or collapse top-to-bottom or left-to-right.
Step by step process to create a simple ajax collapsible panel extender
Step1: Drag Script Manager from Toolbox Ajax Extensions first then drag Label control its id is lblRegister
<asp:Label ID="lblRegister" runat="server" Font-Names="Verdana" 
Font-Size="9pt" Text="Register"></asp:Label>
Step2: Drag Panel control inside panel control Design Register form with TextBoxs and button control.
<asp:Panel ID="PnlRegister" runat="server" BackColor="#999999? 
Font-Names="Verdana" Font-Size="9pt" Width="300px">
<table>
<tr>
<td>Name</td>
<td><asp:TextBox ID="txtName? runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>Email</td>
<td><asp:TextBox ID="txtEmailID? runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><asp:Button ID="btnRegister? runat="server" Text="Register" /></td>
</tr>
</table>
</asp:Panel>
Step3: Drag CollapsiblePanelExtender from Ajax control toolkit
<cc1:CollapsiblePanelExtender ID="CollapsiblePanelExtender1? runat="server">
</cc1:CollapsiblePanelExtender>
Explanation: The collapsiblePanelExtender will take action when 
user click Label (lblRegister) control then the register panel 
will collapse and to  expand also click label (lblRegister)
<cc1:CollapsiblePanelExtender ID="CollapsiblePanelExtender1? 
runat="server"
CollapseControlID="lblRegister"
ExpandControlID="lblRegister"
TargetControlID="PnlRegister"
Collapsed="True" >
</cc1:CollapsiblePanelExtender>
Remember: Target controls ID must be always Panel control. For Expand and Collapse ID is Label or LinkButton control
Complete code for CollapsiblePanelExtender Example
<asp:ScriptManager ID="ScriptManager1? runat="server"> </asp:ScriptManager>
<div style="width: 300px">
<asp:Label ID="lblRegister" runat="server" Font-Names="Verdana" Font-Size="9pt"
Text="Register" BackColor="#FFCC66?></asp:Label>
<br />
<asp:Panel ID="PnlRegister" runat="server" BackColor="#999999? 
Font-Names="Verdana" Font-Size="9pt" Width="300px">
<table>
<tr>
<td>Name</td>
<td><asp:TextBox ID="txtName? runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>EmailID</td>
<td><asp:TextBox ID="txtEmail? runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><asp:Button ID="btnRegister? runat="server" Text="Register" /></td>
</tr>
</table>
</asp:Panel>
<cc1:CollapsiblePanelExtender ID="CollapsiblePanelExtender1? runat="server"
CollapseControlID="lblRegister"
ExpandControlID="lblRegister"
TargetControlID="PnlRegister"
Collapsed="True" >
</cc1:CollapsiblePanelExtender>
<br />
</div>
Step4: Now Run the application you will observe Register (label control) by clicking this control User Registration form(Panel control) will collaspe to expand click same label control(Register).
To Remove ajax collapsiblepanel flicker
keep properties of
AutoCollapse = false
AutoExpand = false
in CollapsiblePanelExtender

How to identify a process is running using asp.net

Function for checking any process is running

//Namespaces we need to use
using System.Diagnostics;
public bool IsProcessOpen(string name)
{
       //here we're going to get a list of all running processes on
       //the computer
       foreach (Process clsProcess in Process.GetProcesses()) {
              //now we're going to see if any of the running processes
              //match the currently running processes. Be sure to not
              //add the .exe to the name you provide, i.e: NOTEPAD,
              //not NOTEPAD.EXE or false is always returned even if
              //notepad is running.
              //Remember, if you have the process running more than once,
              //say IE open 4 times the loop thr way it is now will close all 4,
              //if you want it to just close the first one it finds
              //then add a return; after the Kill
              if (clsProcess.ProcessName.Contains(name))
              {
                     //if the process is found to be running then we
                     //return a true
                     return true;
              }
       }
       //otherwise we return a false
       return false;
}
How to run application from asp.net
Process psToLaunch = new Process();
        public void LaunchProcess()
        {  
            try 
            {  
                Process psToLaunch = new Process();
                psToLaunch.StartInfo.FileName = "notepad.exe";
                psToLaunch.Start();
            }
            catch (Exception ex)
            {
                throw new Exception("error on LaunchProcess() : " + ex.Message);
            }
        }