ASpeak IOpine!

Resize Modal Dialog Box dynamically

Posted on April 2, 2009

This has been a pesky issue in our current project. The requirement is to pop a modal dialog box from a web form. This dialog that appears will contain various user controls based on certain conditions. It may have controls like textbox, tree view, list view, combo box and many others. User will have to select or provide appropriate values in the required fields in this box.

The problem was that the size of the dialog box can not be predetermined and must be generated based on the content of the window. Unlike windows, in web forms we can not generate the pixel sizes of each control and the sum up the vertical space acquired by it and assign that size to the window. Even if it exists I am not aware of it and it might take good amount of time for each form display for each and every user which would be a performance lag. I found a very elegant solution to resize the window as per its content dynamically after the loading of the window. Following is the code snippet for the same:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="frmDyna.aspx.cs" Inherits="frmDyna" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<script language="javascript" type="text/javascript">
    function PerformResize() {
        ht = (document.body.scrollHeight + 32) + 'px'
        wt = (document.body.scrollWidth + 16) + 'px'
        window.dialogHeight = ht;
        window.dialogWidth = wt;
 
    }
</script>
<body onLoad="PerformResize();">
    <form id="form1" runat="server">
    <asp:Panel ID="Panel1" runat="server" BorderStyle="Dotted" 
        Direction="LeftToRight" Wrap="False">    
    </asp:Panel>
    </form>
</body>
</html>

The caller would use following syntax to call the above form as a modal dialog:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
<script language="javascript" type="text/javascript">
    function OpenChild() 
    {
        var WinSettings = "center:yes;resizable:yes;scroll:1;status:0";
        var MyArgs = window.showModalDialog("frmDyna.aspx", null, WinSettings);        
    }
</script>
 
    <form id="form1" runat="server">
    <asp:Panel ID="pnlDyna" runat="server">
        <Button ID="Button1" onclick="OpenChild()"> Button1 </Button>                        
    </asp:Panel>
    </form>
</body>
</html>
Filed under: ASP.NET, DotNET 3 Comments

Lambda based reflection Vs Normal reflection Vs Direct call

Posted on March 25, 2009

One friend of mine sent me the following code sample that really surprised me.

There are three different approaches being used to call a method from a different class. The approaches are -

  1. Direct Call
  2. Call through Lambda based reflection
  3. Call through Normal Reflection

It was really surprising to see the execution speed comparison between three different approaches. The lambda based approach was found to be the fastest by the order of 1000 times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
 
namespace LambdaReflection
{
 
    class MyClass
    {
        public void CallIt()
        {
        }
    }
 
    class Program
    {
        delegate void LocalDel<t>(T mc);
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            MethodInfo minfo = typeof(MyClass).GetMethod("CallIt", BindingFlags.Instance | BindingFlags.Public);
            MyClass obj = new MyClass();
 
            //compile expression tree
            LocalDel<myclass> lambdaExpression = FuncCallIt<myclass>("CallIt");
            sw.Reset();
            sw.Start();
 
            //Direct call by using object
            for (int a = 0; a &lt; 10000; a++)
            {
                obj.CallIt();
            }
            sw.Stop();
            Console.WriteLine(string.Format("Time taken by Direct call {0}", sw.ElapsedTicks));
            sw.Reset();
            sw.Start();
 
            //dynamically compiled lambda call
            for (int a = 0; a &lt; 10000; a++)
            {
                lambdaExpression(obj);
            }
            sw.Stop();
            Console.WriteLine(string.Format("Time taken by lambda-expression compilation {0}", sw.ElapsedTicks));
            sw.Reset();
            sw.Start();
 
            //reflection call
            for (int a = 0; a &lt; 10000; a++)
            {
                minfo.Invoke(obj, null);
            }
            sw.Stop();
            Console.WriteLine(string.Format("Time taken by Reflection call {0}", sw.ElapsedTicks));
            Console.ReadLine();
 
        }
        private static LocalDel<t> FuncCallIt<t>(string MethodName)
        {
            var target = Expression.Parameter(typeof(T), "a");
            MethodInfo minfo = typeof(T).GetMethod(MethodName, BindingFlags.Instance | BindingFlags.Public);
            var methodinvokeExpression = Expression.Call(target, minfo);
            var lambda = Expression.Lambda<localdel><t>&gt;(methodinvokeExpression, new ParameterExpression[] { target });
            return lambda.Compile();
        }
    }
}

Following is the result of the execution on my system:

Time taken by Direct call 2384625

Time taken by lambda-expression compilation 902430

Time taken by Reflection call 518534265

I didn’t expect lambda based call to be faster than direct call but I need to explore as how best I can make use of this knowledge in my real programming scenarios. The compiled lambda demands different compiled lambda expressions for each method being used. However, if performance is the prime objective in the application then I think this tangential approach is worth considering.

What is your opinion on it ?

Mark File for deletion on reboot

Posted on March 24, 2009

Requirement: Delete files from a given folder using C#.

Challenge: The file may be in use i.e. locked.

Approach: Use System Call to mark file for deletion on restart

Solution: Use PInvoke for MoveFileEx.

///
/// Consts defined in WINBASE.H
///
internal enum MoveFileFlags
{
    MOVEFILE_REPLACE_EXISTING = 1,
    MOVEFILE_COPY_ALLOWED = 2,
    MOVEFILE_DELAY_UNTIL_REBOOT = 4,
    MOVEFILE_WRITE_THROUGH  = 8
}
 
 
/// <summary>
/// Marks the file for deletion during next system reboot
/// </summary>
/// <param name="lpExistingFileName">The current name of the file or directory on the local computer.</param>
/// <param name="lpNewFileName">The new name of the file or directory on the local computer.</param>
/// <param name="dwFlags">MoveFileFlags</param>
/// <returns>bool</returns>
/// <remarks>http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx</remarks>
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll",EntryPoint="MoveFileEx")]
internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
MoveFileFlags dwFlags);
 
//Usage for marking the file to delete on reboot
MoveFileEx(fileToDelete, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);

The file is marked for deletion in registry in following location

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerPendingFileRenameOperations

Uninstallation from C#

Posted on March 17, 2009

I wanted to programatically uninstall an application installed in my system. Following code is a working piece to uninstall any custom application from the system.

Note: Following code snippet is not the best example of good coding standards ! It was just a sample I was trying to use to achieve something. The code is a mixture of coding styles lifted across various sites. Please excuse for that :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private static int Uninstall()
{
        Microsoft.Win32.RegistryKey Fregistry =
        Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE")
        .OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion")
        .OpenSubKey("Installer").OpenSubKey("UserData")
        .OpenSubKey("S-1-5-18").OpenSubKey("Products");
        string[] Names = Fregistry.GetSubKeyNames();
        string uninstall = "";
        string ApplicationName = "My Custom Application";
        for (int i = 0; i < Names.Length; i++)
        {
            Microsoft.Win32.RegistryKey FTemp = Fregistry.OpenSubKey(Names[i]).OpenSubKey("InstallProperties");
            if (FTemp == null)
                continue;
            string appFound = (FTemp.GetValue("DisplayName") == null) ? String.Empty : FTemp.GetValue("DisplayName").ToString();
            if (!String.IsNullOrEmpty(appFound))
                System.Diagnostics.Trace.WriteLine("Found Software: " + appFound);
            if (String.Compare(appFound, ApplicationName, true) == 0)
            {
                String installedVersion = FTemp.GetValue("DisplayVersion").ToString();
                if (!installedVersion.StartsWith("3.1."))//can be removed if only one version is installed
                    continue;
                object obj = FTemp.GetValue("UninstallString");
                if (obj == null)
                    uninstall = "";
                else
                    uninstall = obj.ToString();
                i = Names.Length;
            }
        }
        if (String.IsNullOrEmpty(uninstall))
        {
            return -1;
        }
        System.Console.WriteLine(uninstall);
        System.Diagnostics.Process FProcess = new System.Diagnostics.Process();
        string temp = "/passive /x{" + uninstall.Split("/".ToCharArray())[1].Split("I{".ToCharArray())[2];
        FProcess.StartInfo.FileName = uninstall.Split("/".ToCharArray())[0];
        FProcess.StartInfo.Arguments = temp;
        FProcess.StartInfo.UseShellExecute = false;
        FProcess.Start();
        FProcess.WaitForExit();
        if (FProcess.ExitCode != 0)
            return -1;
        else
        {
            return 0;
        }
}
Tagged as: , No Comments

Remote Debugging with VS2008

Posted on December 4, 2008
Remote Debugging

Remote Debugging

This is a very common development requirement and many of you might be knowing this thing already. However, I am just putting this information as it might help someone. In a distributed development scenario it becomes imminent to have remote debugging possible lest you have your development environment both on your regular development system and the remote server where the webapp is deployed. However, this problem could be resolved if we try to use remote debugging. It is easy to do with Visual Studio.NET. I am using VS2008 but the same should apply to 2005 as well with minor changes.

All you need to do is to copy C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger\ folder from your local development system having VS2008 to the remote system which you want to debug. On remote system you can launch msvsmon.exe and also you can create a desktop shortcut for the same to make it easy to launch everytime. The user launching this app must be an admin to provide full previledges else you should use run as to launch this application with administrator rights.

More information could be found from
http://www.wictorwilen.se/Post/How-to-get-Remote-Debugging-work-properly.aspx