Wednesday, May 16, 2012

Send mail using Microsoft Outlook



Already posted how to mail using SMTP; but now in this implemenation will show how to send mail using Microsoft Outlook object.
But there a basic rule of these implementation:
  1. Create the required objects.
  2. Add recepient, main subject, mail body, attachment.
  3. Send mail and validate.
  4. Release resources.
Implementation:
using Outlook = Microsoft.Office.Interop.Outlook;

public void SendTestMail()
{
    try
    {
        Outlook.Application otApp = new Outlook.Application();// create outlook object
        Outlook.NameSpace ns = otApp.Session;
        Outlook.MailItem otMsg = (Outlook.MailItem)otApp.CreateItem(Outlook.OlItemType.olMailItem); // Create mail object
        Outlook.Inspector oInspector = otMsg.GetInspector;
        Outlook.Recipient otRecip = (Outlook.Recipient)otMsg.Recipients.Add("abc@xyz.com");
        otRecip.Resolve();// validate recipient address
        otMsg.Subject = "test subject";
        otMsg.Body = "text message";
        String sSource = "C:\\Test.txt";
        String sDisplayName = "TestAttachment";
        int iPos = (int)otMsg.Body.Length + 1;
        int iAttType = (int)Outlook.OlAttachmentType.olByValue;  
        Outlook.Attachment oAttach = otMsg.Attachments.Add(sSource,iAttType,iPos,sDisplayName); // add attachment
        otMsg.Save();
        otMsg.Send(); // Send Mail
        otRecip = null;
        otAttach = null;
        otMsg = null;
        otApp = null;
    }
    catch (Exception e)
    {
        Console.WriteLine("{0} Exception caught: ", e);
    }
    return 0;
}

Thursday, May 10, 2012

New Features in .NET Framework 3.5 for C# Form

I tried to collect all the relevant improvements regarding .NET 3.5 w.r.t. forms for my quick reference. I will be glad if someone also gets value from it. All the information below are from MSDN.

Collections
HashSet<T> provides high performance set operations to the .NET Framework. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.

Diagnostics
The EventSchemaTraceListener class provides tracing of end-to-end, schema-compliant events. You can use end-to-end tracing for a system that has heterogeneous components that cross thread, AppDomain, process, and computer boundaries. A standardized event schema (see Event Representation for Event Consumers) has been defined to enable tracing across these boundaries. This schema is shared by various tracing technologies, including Windows Vista diagnostics tools such as Event Viewer. The schema also enables the addition of custom, schema-compliant elements.

The EventSchemaTraceListener class is tuned for logging performance with implicit support for lock-free tracing.

I/O and Pipes
Pipes provide inter-process communication between any processes running on the same computer, or on any other Windows computer within a network. The .NET Framework provides access to two types of pipes: anonymous pipes and named pipes. For more information about pipes.

Garbage Collection
The GCSettings class has a new LatencyMode property that you can use to adjust the time that the garbage collector intrudes in your application. You set this property to one of the values of the new GCLatencyMode enumeration.

The GC class has a new Collect(Int32, GCCollectionMode) method overload that you can use to adjust the behavior for a forced garbage collection. For example, you can use this overload to specify that the garbage collector should determine whether the current time is optimal to reclaim objects. This overload takes a value from the new GCCollectionMode enumeration.

Reflection and Reflection Emit in Partial Trust
Assemblies that run with partial trust can now emit code and execute it. Emitted code that calls only public types and methods needs no permissions beyond the permissions demanded by the types and methods that are accessed. The new DynamicMethod(String, Type, Type[]) constructor makes it easy to emit such code.

When emitted code needs to access private data, the new DynamicMethod(String, Type, Type[], Boolean) constructor allows restricted access. The host must grant ReflectionPermission with the new RestrictedMemberAccess flag to enable this feature, which gives emitted code the ability to access private data only for types and methods in assemblies with equal or lesser trust levels. See Walkthrough: Emitting Code in Partial Trust Scenarios.

For reflection, a host grant of RestrictedMemberAccess similarly allows restricted use of methods that access private properties, call private methods, and so on, but only for target assemblies with equal or lesser trust levels.

Threading
1. Better Reader/Writer Lock
The new ReaderWriterLockSlim class provides performance that is significantly better than ReaderWriterLock, and comparable with the lock statement (SyncLock in Visual Basic). Transitions between lock states have been simplified to make programming easier and to reduce the chances of deadlocks. The new class supports recursion to simplify migration from lock and fromReaderWriterLock.

2. ThreadPool Performance Enhancements
Throughput for the dispatch of work items and I/O tasks in the managed thread pool is significantly improved. Dispatch is now handled in managed code, without transitions to unmanaged code and with fewer locks. The use of ThreadPool is recommended over application-specific thread pool implementations.

3. Time Zone Improvements
Two new types, DateTimeOffset and TimeZoneInfo, improve support for time zones and make it easier to develop applications that work with dates and times in different time zones. For a discussion of which type to use in particular situations, see Choosing Between DateTime, DateTimeOffset, and TimeZoneInfo.

4. TimeZoneInfo
The new TimeZoneInfo class largely supplants the existing TimeZone class. You can use TimeZoneInfo to retrieve any time zone defined in the registry, rather than just the local time zone and Coordinated Universal Time (UTC). You can also use this class to define custom time zones, to serialize and deserialize custom time zone data, and to convert times between time zones. For more information about developing applications that use the TimeZoneInfo class, see Times and Time Zones.

5. DateTimeOffset
The new DateTimeOffset structure extends the DateTime structure to make working with times across time zones easier. The DateTimeOffset structure stores date and time information as a UTC date and time together with an offset value that indicates how much the time differs from UTC.

ClickOnce Improvements
Several improvements have been made to ClickOnce. Improvements include deployment from multiple locations and third-party branding. For more information, see Deploying ClickOnce Applications without Resigning and Creating ClickOnce Applications for Others to Deploy.

The Mage.exe tool, which is sometimes used together with ClickOnce, has been updated for the .NET Framework 3.5. For more information, see Manifest Generation and Editing Tool (Mage.exe).

ClickOnce Manifests
There are new cryptography classes for verifying and obtaining information about manifest signatures for ClickOnce applications. The ManifestSignatureInformation class obtains information about a manifest signature when you use its VerifySignature method overloads. You can use the ManifestKinds enumeration to specify which manifests to verify. The result of the verification is one of the SignatureVerificationResult enumeration values. The ManifestSignatureInformationCollection provides a read-only collection of ManifestSignatureInformation objects of the verified signatures.

In addition, the following classes provide specific signature information:
StrongNameSignatureInformation Holds the strong name signature information for a manifest.
AuthenticodeSignatureInformation Represents the Authenticode signature information for a manifest.
TimestampInformation Contains information about the time stamp on an Authenticode signature.
TrustStatus Provides a simple way to check whether an Authenticode signature is trusted.

Suite B Support
The .NET Framework 3.5 supports the Suite B set of cryptographic algorithms published by the National Security Agency (NSA). For the NSA documentation, see www.nsa.gov/ia/industry/crypto_suite_b.cfm.

The following algorithms are included:
  • Advanced Encryption Standard (AES) with key sizes of 128 and 256 bits for encryption.
  • Secure Hash Algorithm (SHA-256 and SHA-384) for hashing.
  • Elliptic Curve Digital Signature Algorithm (ECDSA) using curves of 256-bit and 384-bit prime moduli for signing. This algorithm is provided by the ECDsaCng class. It allows you to sign with a private key and verify with a public key.
  • Elliptic Curve Diffie-Hellman (ECDH) using curves of 256 and 384-bit prime moduli for key exchange/secret agreement. This algorithm is provided by the ECDiffieHellmanCng class.

Authentication, Roles, and Settings Services
Client application services are new in the .NET Framework 3.5 and enable Windows-based applications (including Windows Forms and Windows Presentation Foundation applications) to easily access the ASP.NET login, roles, and profile services. These services enable you to authenticate users and retrieve user roles and application settings from a shared server.

You can enable client application services by specifying and configuring client service providers in your application configuration file or in the Visual Studio Project Designer. These providers plug into the Web extensibility model and enable you to access the Web services through existing .NET Framework login, roles, and settings APIs. Client application services also support occasional connectivity by storing and retrieving user information from a local data cache when the application is offline.

For more information, see Client Application Services.

Windows Vista Support
Existing Windows Forms applications work seamlessly on Windows Vista, and they are upgraded to have the same appearance as applications written specifically for Windows Vista whenever possible. Common file dialog boxes are automatically updated to the Windows Vista version. The .NET Framework 3.5 also supports the User Account Control (UAC) Shield icon. For more information, see FileDialog Class and Shield.

WPF support
You can use Windows Forms to host Windows Presentation Foundation (WPF) controls and content together with Windows Forms controls. You can also open WPF windows from a Windows Form. For more information about how to use Windows Forms and WPF together, see Migration and Interoperability.

LINQ
LINQ extends powerful query capabilities to the language syntax of C# and Visual Basic in the form of standard, easily-learned query patterns. This technology can be extended to support potentially any kind of data store. The .NET Framework 3.5 includes LINQ provider assemblies that enable the use of LINQ for querying .NET Framework collections, SQL Server databases, ADO.NET Datasets, and XML documents.

The components of LINQ that are part of the .NET Framework 3.5 are:
  • The System.Linq namespace, which contains the set of standard query operators and types and interfaces that are used in the infrastructure of a LINQ query. This namespace is in the System.Core.dll assembly.
  • The System.Data.Linq namespace, which contains classes that support interaction with relational databases in LINQ to SQL applications.
  • The System.Data.Linq.Mapping namespace, which contains classes that can be used to generate a LINQ to SQL object model that represents the structure and content of a relational database.
  • The System.Xml.Linq namespace, which contains the classes for LINQ to XML. LINQ to XML is an in-memory XML programming interface that enables you to modify XML documents efficiently and easily. Using LINQ to XML, you can load XML, serialize XML, create XML trees from scratch, manipulate in-memory XML trees, and validate by using XSD. You can also use a combination of these features to transform XML trees from one shape into another.
  • New types in System.Web.UI.WebControls and System.Web.UI.Design.WebControls namespaces. These new types, such as LinqDataSource, support the use of LINQ in ASP.NET Web pages through a data source control.
  • The DataRowComparer, DataRowExtensions, and DataTableExtensions classes in the System.Data namespace support LINQ queries against ADO.NET DataSet objects.






Wednesday, May 9, 2012

Execute functions dynamically using Reflection


Using Reflection you can execute any methods or constructor dynamically. This is something on the line of functional pointer but with some improvement. One of the notable improvements is unlike functional pointer you can pass the method name in string variable to execute.

There are couple of ways to do that and both the ways are described below.

What’s the use of it – for me I had a specific requirement of retrieving list of data in List for further use. But this implementation needed and generic and user friendly approach. In future if there is a requirement of separate list then it can be added easily.

Implementation

Functionality for creating list

public class TestClass
{
      void _LIST(List<string[]> lList, string sNumber, string sAlphaData)
      {
            string[] sData = new string[2];
            sData[0] = sNumber;
            sData[1] = sAlphaData;
            lList.Add(sData);
      }
//Sample functions which will be called dynamically
//If you observe the functions for adding a new list user need to add new function in the format
//below and using a generic function call it dynamically
      public void function_1(List<string[]> lTestList)
      {
            _LIST(lTestList, "0", "Test 1");
            _LIST(lTestList, "2", "Test 2");
      }
      public void function_2(List<string[]> lTestList)
      {
            _LIST(lTestList, "A", "Alpha 1");
            _LIST(lTestList, "B", "Alpha 2");
      }
}

Generic function which has one parameter (string) in which function name will be passed.
This generic function can be implemented in couple of ways:

Using Activator
public string ExecuteFunction(string sFunationName)
{
      List<string[]> lTestList = new List<string[]>();
      Type FuncType = this.GetType();
      object[] mParam = new object[] { lTestList };
      object obj = Activator.CreateInstance(FuncType);
      FuncType.InvokeMember(sFunationName, BindingFlags.InvokeMethod, null, obj, mParam);
      // at this point lTestList get populated with data which can be used as per user discretion
}

Using Reflection
public string ExecuteFunction(string sFunationName)
{
      TestClass testClass = new TestClass();
      List<string[]> lTestList = new List<string[]>();
      Type FuncType = typeof(TestClass);
      MethodInfo miFunationName = FuncType.GetMethod(sFunationName);
      object[] mParam = new object[] { lTestList };
      miFunationName.Invoke(testClass, mParam);
      // at this point lTestList get populated with data which can be used as per user discretion
}

Thursday, May 3, 2012

WiX Research - Building Installer using WiX Sharp partially


Looking beyond WiX Sharp…

Here is another implementation of WiX as a part of on-going research. In the following implementation I have used few features of WiX Sharp and predominantly WiX to build an installer (.msi). This is unlike the previous implementation where I have user WiX Sharp only.

What is the requirement of further refining the implementation? 
And what is the requirement of moving away from WiX Sharp?

I see there are few shortcomings using WiX Sharp:
  • There is a dependency on third party tool (WiX Sharp) which may go against proprietary norms of the company.
  • There are many features implemented or can be tweaked in WiX as per user requirement; which may not possible if we are heavily dependent in WiX Sharp.
  • Having your own middle tier will give more control over your implementation.


Note :- I am really a fan of WiX Sharp and see value it has but on the other hand when thought of it rationally compelled me to look beyond WiX Sharp.

Salient features of the implementation:
  • Building .wxs file using WiX Sharp.
  • Integrating custom installation path using System.XML.LINQ.
  • Executing Candle.exe and Light.exe using System.Diagnostics.Process to build the installer.


Feedback are appreciated to improve implementation and if I am missing out anything.

ExeEXE – Standard function to call System.Diagnostics.Process to execute EXE and get the return value.

public bool ExeEXE(string sApplication, string sAppArgs)
{
    System.Diagnostics.Process AppProcess = new System.Diagnostics.Process();
    AppProcess.StartInfo.FileName = sApplication;
    AppProcess.StartInfo.Arguments = sAppArgs;
    AppProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    AppProcess.Start();
    AppProcess.WaitForExit();
    if (AppProcess.ExitCode > 0)
        Errorobj = "Error excounter while executing " + sApplication + " in " + this.ToString();
    else
        Errorobj = null;
    return (AppProcess.ExitCode == 0) ? true : false;
}

InsertCustomPath – This function insert Custom action in .wxs file for assigning custom path

private void InsertCustomPath()
{
    XDocument Doc = XDocument.Load(Environment.CurrentDirectory + @"\Test Product.wxs");
    if (Doc.Root != null)
    {
        XNamespace xNS = Doc.Root.GetDefaultNamespace();
        XElement xCustAct = new XElement(xNS + "CustomAction",
                                         new XAttribute("Id", "CustActSetINSTALLDIR"),
                                         new XAttribute("Return", "check"),
                                         new XAttribute("Execute", "firstSequence"),
                                         new XAttribute("Property", "TARGETDIR"),
                                         new XAttribute("Value", sInstDir));
        XElement xUI = new XElement(xNS + "UI",
                                    new XElement(xNS + "InstallUISequence",
                                                 new XElement(xNS + "Custom",
                                                              new XAttribute("Action", "CustActSetINSTALLDIR"),
                                                              new XAttribute("After", "ValidateProductID"), "TARGETDIR=\"\"")));
        XElement xExeSeq = new XElement(xNS + "InstallExecuteSequence",
                                        new XElement(xNS + "Custom",
                                                     new XAttribute("Action", "CustActSetINSTALLDIR"),
                                                     new XAttribute("After", "ValidateProductID"), "TARGETDIR=\"\""));
        XNode Node = Doc.Root.FirstNode;
        while (Node != null)
        {
            if (((XElement)Node).Name.LocalName == "Product")
            {
                XNode ChildNode = ((XElement)Node).FirstNode;
                while (ChildNode != null)
                {
                    if (((XElement)ChildNode).Name.LocalName == "Directory")
                    {
                        ChildNode.AddAfterSelf(xCustAct);
                    }
                    else if (((XElement)ChildNode).Name.LocalName == "Upgrade")
                    {
                        ChildNode.AddAfterSelf(xExeSeq);
                        ChildNode.AddAfterSelf(xUI);
                    }
                    ChildNode = ChildNode.NextNode;
                }
            }
            Node = Node.NextNode;
        }
    }
    Doc.Save(Environment.CurrentDirectory + @"\Test Product.wxs");
}

BuildInstaller – Main function to build .wxs and then execute Candle.exe and Light.exe.

public object BuildInstaller()
{
    try
    {
        WixEntity[] weDir1 = new WixEntity[0];
        weDir1 = BuildDirInfo(sRootDir, weDir1); // Implementation already been described in previous post
        var project = new Project("Test Product", new Dir("Test Product", weDir1))
        {
            GUID = Guid.NewGuid(),
            UI = WUI.WixUI_InstallDir,
            Manufacturer = "Test Company",
            Version = new Version(1, 1, 1, 0),
            LicenceFile = Directory.GetCurrentDirectory() + @"\EULA.rtf",
            BannerImage = Directory.GetCurrentDirectory() + @"\Banner.bmp",
            BackgroundImage = Directory.GetCurrentDirectory() + @"\Background.bmp",
            UpgradeCode = guidUpgradeCode,
            MajorUpgradeStrategy = new MajorUpgradeStrategy
            {
                UpgradeVersions = VersionRange.OlderThanThis,
                PreventDowngradingVersions = VersionRange.NewerThanThis,
                NewerProductInstalledErrorMessage = "Newer version already installed"
            }
        };
        
        // Building .wxs file using WixSharp.dll
        Compiler.BuildWxs(project, Environment.CurrentDirectory + @"\Test Product.wxs");
        
        InsertCustomPath();// Inserting Custom action for setting custom installation path
        
        //Executing Candle.exe and Light.exe using System.Diagnostics.Process
        string sCommandLine = "\"" + Environment.CurrentDirectory + "\\Test Product.wxs\" -out \"" + Environment.CurrentDirectory + "\\Test Product.wixobj\"";
        if (ExeEXE(Environment.CurrentDirectory + @"\wixbin\bin\Candle.exe", sCommandLine))
        {
            System.IO.File.Delete(Environment.CurrentDirectory + "\\Test Product.wxs");
            sCommandLine = "\"" + Environment.CurrentDirectory + "\\Test Product.wixobj\" -ext WixUIExtension -out \"" + sInstLoc + "\\Test Product.msi\"";
            if (!ExeEXE(Environment.CurrentDirectory + @"\wixbin\bin\Light.exe", sCommandLine))
            {
                obRtn = "ERROR: " + (string)Errorobj;
                return obRtn;
            }
            System.IO.File.Delete(Environment.CurrentDirectory + "\\Test Product.wixobj");
            System.IO.File.Delete(sInstLoc + "\\Test Product.wixpdb");
        }
        else
        {
            obRtn = "ERROR: " + (string)Errorobj;
            return obRtn;
        }
        return obRtn;
    }
    catch (Exception w)
    {
        MessageBox.Show(w.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return null;
}

Tuesday, May 1, 2012

WiX Research - Building Installer (.msi) using WiX Sharp

This is a part of series of research which I am doing for finding out a better way to create and Installer. Just building an installer is not something I am looking into, I am looking forward to build a installer which is efficient and easy to maintain (Installer as well as source code).

Objective
Using WiXSharp build installer (.msi) with following objective fulfilled:
  • Build installer of a folder location specified.
  • Installer should able to upgrade and not allow downgrade.

Set Environment Variable
Before doing anything using WiXSharp need to set environment variables which will ack as beacon for WiX bin. Call this somewhere like while initializing the class.

public void ReBuildInstallerEnvironment()
{
    Environment.SetEnvironmentVariable("WIXSHARP_WIXDIR", Environment.CurrentDirectory + @"\Wix_bin\bin", EnvironmentVariableTarget.Process);
    Environment.SetEnvironmentVariable("WIXSHARP_DIR", Environment.CurrentDirectory, EnvironmentVariableTarget.Process);
}

There are quiet a few ways to create .msi using WiXSharp but after doing some research found that rather than directly assigning data in the WiXSharp Project it is better create WixEntity objects are pass it to the Project.

Create WixEntity[] 
To build installer using WiXSharp need to create WixEntity[] of the folder and its files within. To achieve that created following recursive code.

private WixEntity[] BuildDirInfo(string sRootDir, WixEntity[] weDir)
{
    DirectoryInfo RootDirInfo = new DirectoryInfo(sRootDir);
    if (RootDirInfo.Exists)
    {
        DirectoryInfo[] DirInfo = RootDirInfo.GetDirectories();
        List<string> lMainDirs = new List<string>();
        foreach (DirectoryInfo DirInfoSub in DirInfo)
            lMainDirs.Add(DirInfoSub.FullName);
        int cnt = lMainDirs.Count;
        weDir = new WixEntity[cnt + 1];
        if (cnt == 0)
            weDir[0] = new DirFiles(RootDirInfo.FullName + @"\*.*");
        else
        {
            weDir[cnt] = new DirFiles(RootDirInfo.FullName + @"\*.*");
            for (int i = 0; i < cnt; i++)
            {
                DirectoryInfo RootSubDirInfo = new DirectoryInfo(lMainDirs[i]);
                if (!RootSubDirInfo.Exists) 
                    continue;
                WixEntity[] weSubDir = new WixEntity[0];
                weSubDir = BuildDirInfo(RootSubDirInfo.FullName, weSubDir);
                weDir[i] = new Dir(RootSubDirInfo.Name, weSubDir);
            }
        }
    }
    return weDir;
}

Build Installer
Now create your own function to build .msi using WiXSharp.
WiXSharp is a very easy to implement utility which has been built over WiX.

void BuildInstaller()
{
       WixEntity[] weDir = new WixEntity[0];
       weDir = BuildDirInfo(sRootDir, weDir);
       var project = new Project("Test Product", new Dir("TestProduct", weDir))
       {
              GUID = Guid.NewGuid(),
              UI = WUI.WixUI_InstallDir,
              Manufacturer = "TestCompany",
              Version = new Version(12, 1, 1, 0),
              LicenceFile = Directory.GetCurrentDirectory() + @"\EULA.rtf",
              BannerImage = Directory.GetCurrentDirectory() + @"\Banner.bmp",
              BackgroundImage = Directory.GetCurrentDirectory() + @"\Background.bmp",
              UpgradeCode = guidUpgradeCode, // Forwarded if upgrading existing product
              MajorUpgradeStrategy = new MajorUpgradeStrategy
              {
                     UpgradeVersions = VersionRange.OlderThanThis,
                     PreventDowngradingVersions = VersionRange.NewerThanThis,
                     NewerProductInstalledErrorMessage = "Newer version already installed"
              }
       };
       Compiler.BuildMsi(project, sInstLoc + @"\Test Product.msi");
}

There is nothing much into it just you need to know how to play with WixEntity[] and WixEntity class objects.

I will be working on different aspects if WiX in future...