Tuesday, June 29, 2010

How to: List all files in a Drive using C#

The code below shows how to use the System.IO.DirectoryInfo function to retreive all the files in the specified location, it also show how to get the extension and other information. Here in this code sample checking for DriveType CD Rom and files in that CD Drive.

Here is a sample code snippet for doing this. Have fun!

System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
string strDriverLetter = "";
bool boolDriveIsReady = false;
foreach (System.IO.DriveInfo drive in drives)
{
    if (drive.DriveType == System.IO.DriveType.CDRom)
    {
        Console.WriteLine("Drive Name: " + drive.Name);
        strDriverLetter = drive.Name;
        boolDriveIsReady = drive.IsReady;
        break;
    }
}
if (boolDriveIsReady == true)
{
    boolDriveIsReady = false;
    DirectoryInfo di = new DirectoryInfo(strDriverLetter);
    FileInfo[] exFiles = di.GetFiles("*.exe");
    foreach (FileInfo fi in exFiles)
    {
        Console.WriteLine("File Name: " + fi.Name + "Extension "+ fi.Extension);
        if (fi.Name.ToUpper().Equals("LAUNCH.EXE"))
        {                        
            boolDriveIsReady = true;
            break;
        }
    }
}

Friday, June 25, 2010

How to: Running Windows service at a specified time period.

I am writing an Notification service, for that i need to send reminders based on a time period. This is how I did. Here i am Configuring notification time and service interval time in app.config. For me, notification time is the time when to execute the logic and service interval time will tell the timer when to stop and start. If we want we can make this data driven as well. I have added a timer control. Here is the sample code snippet here for this.

public partial class Service1 : ServiceBase
{
    private System.Timers.Timer timer = null;
    private NotificationClass nc = new NotificationClass();
    private string notificationTime = ConfigurationManager.AppSettings["notificationTime"];
    // Default time to start and stop the timer.
    private string serviceInterval = ConfigurationManager.AppSettings["serviceInterval"];
    public Service1()
    {
        InitializeComponent();
        timer = new System.Timers.Timer(Convert.ToDouble(serviceInterval));
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    }
    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        // Compare this notification time with your time...
        if (DateTime.Now.ToShortTimeString() == notificationTime)
        {
            this.timer.Enabled = false;
            this.timer.AutoReset = false;
            // Do the logic
            nc.BirthdayReminder();
            this.timer.Start();
        }
    }
    protected override void OnStart(string[] args)
    {
        // TODO: Add code here to start your service.
        timer.AutoReset = true;
        timer.Enabled = true;
        timer.Start();
    }
    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop your service.
        timer.AutoReset = false;
        timer.Enabled = false;
    }
}

Thursday, June 24, 2010

Dynamically Loading Master Pages

Master Pages give you the ability to define a master page layout and look that is used throughout a site to give a consistent look & feel to all pages. Any updates or changes to the look & feel of the site is done in only one place - the Master Page. Something that might be useful is the ability to dynamically load a master page at runtime, for example based on user preferences or to implement a simple skinning ability for a site framework that might host multiple different sites.

The master page can be selected for a page easily at design-time. But assigning a master page at run-time can only be done in the OnPreInit event since the rendering of the page with the master page occurs prior to the Init event. However, in the case where you want to load the master page dynamically, for example from a database entry based on a user's preference or something, you don't want to add code to the OnPreInit event on every page in the site. It is easy enough to add that code to a base page class that you can inherit from for you pages in the site.

public class DynamicPage : System.Web.UI.Page
{
protected override void OnPreInit(EventArgs e)
{
string masterfile = getMasterPageFromDatabase();
if (!masterfile.Equals(string.Empty))
{
base.MasterPageFile = masterfile;
}
base.OnPreInit(e);
}
}


Now, all you have to do is inherit from that class for all the pages in the site. You can just add it into the web.config and all pages will automatically inherit from it. Doesn't matter if it is a page in the project that you have already, or a new page you add later, it will know to inherit from the DynamicPage class. You add the following to the web.config:



<system.web>
<pages pageBaseType="DynamicPage" />
<!-- ...rest of system.web items... -->
</system.web>

Wednesday, June 23, 2010

How to: Adding Uninstall start menu item to your .NET deployment project

Its pretty simple. Follow the steps to achieve this.

  • Add the following code snippet  to your projects main method before InitializeComponent();
    string[] arguments = Environment.GetCommandLineArgs();
    foreach (string argument in arguments)
    {
       string[] parameters = argument.Split('=');
       if (parameters[0].ToLower() == "/u")
       {
         string productCode = parameters[1];
         string path = Environment.GetFolderPath(Environment.SpecialFolder.System);
         Process proc = new Process();
         proc.StartInfo.FileName = string.Concat(path, "\\msiexec.exe");
         proc.StartInfo.Arguments = string.Concat(" /i ", productCode);
         proc.Start();
       }
    }



    • Now go to your deployment project and go to the file system editor and right click on File System on Target Machine and Add Special Folder with name User's Programs Menu.


    • Add an additional shortcut to your primary output project and name it Uninstall.


    • Right Click  Shortcut to Set the Arguments property to /u=[ProductCode].


    • Now Build your Deployment setup project. Your are ready to go.


    Deployment project will replace [ProductCode] in the Arguments property with the actual installer project's ProductCode GUID value. Your program will see the /u={Actual ProductCode} argument and pass it to msiexec.exe. If you want the product to remove only, replace the "/i " with "/x ".

    Tuesday, June 22, 2010

    How to: Check whether SQL login exists?

    Try some thing like this.

    DECLARE @SqlStatement NVARCHAR(4000)
    DECLARE @loginName VARCHAR (100)
    SELECT @loginName = 'nagasai'
    IF NOT EXISTS (SELECT loginname FROM master.dbo.syslogins WHERE NAME = @loginName)
    BEGIN
    SET @SqlStatement = 'CREATE LOGIN [' + @loginName + '] WITH PASSWORD=N''angel83'',DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]'
    EXEC sp_executesql @SqlStatement
    END
    ELSE
    BEGIN
    PRINT 'login name ' + @loginName + ' already exists'
    END

    How to: Create login as sysadmin from T-SQL

    Here is the T-SQL code snippet that creates login with sysadmin permissions.

    CREATE LOGIN [nagasai] WITH PASSWORD=N'angel83', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=ON, CHECK_POLICY=ON
    GO
    EXEC master..sp_addsrvrolemember @loginame = N'nagasai', @rolename = N'sysadmin'

    Friday, June 18, 2010

    How do I debug a custom action/installer class?

    Here is how you can do debug custom action.  You can try using one of the following methods:

    • Add a call in your code to System.Diagnostics.Debugger.Launch. This method opens Just-In-Time debugging and enables you to attach a new debugger to your code.
    • Add a call in your code to MessageBox.Show("Debug Me"). When the message box is shown, use Visual Studio to attach to the MessageBox process. Then add breaks (for Visual C# projects) or stops (for Visual Basic projects) in the code.
    • Set your debugging preferences to start %windir%\Microsoft.net\Framework\version\InstallUtil.exe as an external program on the Debug Page of the Project Designer. The name of the custom action assembly is the command line arguments. When you press F5, you hit your breakpoint. InstallUtil.exe will run your custom actions just as MSI does.

    Life was difficult until i find this solution from MSDN.

    ASP.NET 4 Breaking Changes

    .Net Framework 4.0 comes up with some of major changes as compare to previous versions of .Net Framework 3.5 and 2.0
    Following are list of Major Changes in .Net 4.0

    • ControlRenderingCompatabilityVersion Setting in the Web.config File 
    • ClientIDMode Changes 
    • HtmlEncode and UrlEncode Now Encode Single Quotation Marks 
    • ASP.NET Page (.aspx) Parser is Stricter 
    • Browser Definition Files Updated 
    • System.Web.Mobile.dll Removed from Root Web Configuration File 
    • ASP.NET Request Validation 
    • Default Hashing Algorithm Is Now HMACSHA256 
    • Configuration Errors Related to New ASP.NET 4 Root Configuration 
    • ASP.NET 4 Child Applications Fail to Start When Under ASP.NET 2.0 or ASP.NET 3.5 Applications 
    • ASP.NET 4 Web Sites Fail to Start on Computers Where SharePoint Is Installed 
    • The HttpRequest.FilePath Property No Longer Includes PathInfo Values 
    • ASP.NET 2.0 Applications Might Generate HttpException Errors that Reference eurl.axd 
    • Event Handlers Might Not Be Not Raised in a Default Document in IIS 7 or IIS 7.5 Integrated Mode Changes to the ASP.NET Code Access Security (CAS) Implementation 
    • MembershipUser and Other Types in the System.Web.Security Namespace Have Been Moved 
    • Output Caching Changes to Vary * HTTP Header 
    • System.Web.Security Types for Passport are Obsolete 
    • The MenuItem.PopOutImageUrl Property Fails to Render an Image in ASP.NET 4 
    • Menu.StaticPopOutImageUrl and Menu.DynamicPopOutImageUrl Fail to Render Images When Paths Contain Backslashes 

    Find detail information of ASP.NET 4 Breaking Changes

    Saturday, June 12, 2010

    How to : Detecting CD Drive from C#

    Recently i was writing a custom application which installs on client machine in that i need to find the client CD driver letter.

    Here is an example code snippet for finding driver letter.

    System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
    foreach (System.IO.DriveInfo drive in drives)
    {
      if (drive.DriveType == System.IO.DriveType.CDRom)
      Console.WriteLine(drive.DriveType +"*********" +drive.Name);
    }

    Wednesday, June 09, 2010

    How to: call/Invoke a web service without adding web reference

    Why would anybody want to do this since there is a simple way given by Visual studio by adding a Web Reference from Solution Explorer. But recently wants to build an application which should install in different client locations with different names etc. As in the installer we can give different custom names to virtual directory this will not work for me.  That means “Virtual Directory” can be different for each client in that case i need modify the web reference as per the “Virtual Directory” name of the hosted solution.

    So for that i end up adding proxy class of the web service in my solution by using WSDL tool. I need to generated Proxy class of the web service that i have created and add the proxy class in my Web solution.  For example here is a sample web service code for simplicity

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    namespace SampleWebSerivce
    {
        /// <summary>
        /// Summary description for Service1
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
        // [System.Web.Script.Services.ScriptService]
        public class Service1 : System.Web.Services.WebService
        {
            [WebMethod]
            public string HelloWorld()
            {
                return "Hello World";
            }
        }
    }


    Once your done with your custom web methods, you add the web reference where you actually consume the web service methods. When you add a web reference - based on the WSDL specifications IDE actually creates proxy classes in your application which represents the web service classes and its methods on the remote server



    Visual Studio provides Intellisense with Web services, which will not be accurate till you update your web reference each time you change your web service, it is because the proxy classes which are local to your solution are being used to offer you the Intellisense. So, ultimately when you invoke a Web method you are invoking a method in one of these proxy classes. These classes, in turn, are capable of invoking the remote methods on the Web Service URL.



    So, every time the web service is updated, these proxy classes need to be regenerated by clicking Update Web Reference. However, the proxy classes do not always have to be generated from the IDE, .NET also gives us the WSDL.exe utility to manually generate these proxy classes and include them in your project.



    Here is the syntax to create Proxy class from WSDL tool.wsdl



    Just grab the class, and add in the App_Code folder if its a web site or you can add in root folder if it is a web solution.



    If you open the proxy class you will notice  the constructor of the proxy class contains "url" member property which is by default assigned the url of the website in which the web service exists. You can store the web service url in web.config or in database or as per your logic.



    So, finally to call the "Hello World" web method - you need to create object of this proxy class and assign the url property correctly as below:



    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Service1 objService = new Service1();
            objService.Url =
                System.Configuration.ConfigurationManager.AppSettings["WebServiceUrl"];
            Response.Write("Output of Web method call: " + objService.HelloWorld());
        }
    }


    Finally, You can call web service method without adding Web Reference. But make sure you update the proxy class through WSDL utility as and when you have any changes in the Web Service.