Useful resources on Wix & MSBuild

Rob Mensching's Blog
http://robmensching.com/blog/posts

Wix Edit on Sourceforge
http://wixedit.sourceforge.net/

General forum for Wix users
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/

Primary tutorial for Wix development
http://www.tramontana.co.hu/wix/lesson5.php#5.4

http://www.installworld.com/index.php?view=article&catid=41%3Awindows-installer-xml&id=113%3Awindows-installer-xml-standard-custom-actions&option=com_content&Itemid=137
http://stackoverflow.com/questions/313877/can-i-automate-creating-a-net-web-application-in-iis
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/IIS-actions-failing-td4971548.html

Wix & Burn
http://robmensching.com/blog/posts/2009/7/14/Lets-talk-about-Burn

Great Blog post on Wix
http://blogs.technet.com/b/alexshev/archive/2008/02/10/from-msi-to-wix.aspx

Set Asp.Net Version version Wix

http://stackoverflow.com/questions/163531/set-asp-net-version-using-wix

System folder properties
http://msdn.microsoft.com/en-us/library/aa372057.aspx

Wix article on code project
http://www.codeproject.com/KB/install/WixTutorial2.aspx

Wix toolset
http://wix.sourceforge.net/manual-wix3/files.htm

How do I install an ASP.NET application in IIS 7 using Wix
http://stackoverflow.com/questions/686190/how-do-i-install-an-asp-net-mvc-application-on-iis-7-using-wix

How to use Wix Custom actions with Appcmd.exe to set up virtual folders
http://trac.osgeo.org/mapguide/browser/trunk/Installer/Libraries/MapGuide%20Web%20Extensions/IIS7.wxs#L9

Wix 1419
http://wix.sourceforge.net/releases/3.5.1419.0/

Granting User rights in C#
http://stackoverflow.com/questions/1147914/why-might-lsaaddaccountrights-return-status-invalid-parameter
http://www.codeproject.com/KB/cs/lsadotnet.aspx

Custom Action Element
http://wix.sourceforge.net/manual-wix2/wix_xsd_customaction.htm
http://stackoverflow.com/questions/1213953/c-custom-action-in-wix

Great blog post on elevating priveledges with Custom Action's in Wix
http://blogs.msdn.com/b/astebner/archive/2006/12/13/some-useful-things-i-have-learned-about-windows-installer-and-uac.aspx

Debugging Custom Actions in Wix & Great Wix Resource
http://blog.torresdal.net/CategoryView,category,WiX.aspx

Wix 3.5 IIS Schema elements
http://wix.sourceforge.net/manual-wix3/iis_xsd_index.htm

All the Wix releases can be downloaded from here along with source code
http://wix.sourceforge.net/releases/

Information about ApplicationHost.config
http://learn.iis.net/page.aspx/124/introduction-to-applicationhostconfig/#HowTo

General article on custom actions

http://www.installworld.com/index.php?view=article&catid=41%3Awindows-installer-xml&id=113%3Awindows-installer-xml-standard-custom-actions&option=com_content&Itemid=137

Wix related BUGS and issues with MSBuild
http://blogs.msdn.com/b/msbuild/
http://stackoverflow.com/questions/2656389/why-does-tfs2010-build-my-wix-project-before-anything-else

Msdn article on Wix 2
http://msdn.microsoft.com/en-us/magazine/cc163456.aspx

Using wix with MSBuild

http://wix.sourceforge.net/manual-wix3/wix_with_team_build.htm

All candle variable references

http://blogs.msdn.com/b/jrock/archive/2008/01/29/complete-list-of-candle-preprocessor-variables.aspx

Posted by jean
Filed under:

Adventures with Wix 3.5, Visual Studio 2010 & Team foundation build 2008

Lately I have been having a look at the Microsoft Open Source project named Wix. The goal of this project is to provide an Xml DSL that allows the user to build deployment packages that are wrapped up in a Windows Installer package or ".Msi" file. The user can declare user interfaces that allow for additional meta data to be handed down to the installer and conditional information that will influence the deployment process. The meta data along with the components installed on the machine are registered with the Windows OS and on uninstall the removal instructions are executed which can once again query this meta data. Wix allows you to hook into or extend the component installation event sequence if required and custom actions (written in managed or unmanaged code) can query meta data provided by an Installer custom UI during install and uninstall.

Unfortunately Wix is not always 100% stable, and requires some knowledge of MSBuild and the Microsoft Build Engine.

Rob Mensching who works at Microsoft is the development lead on the project. Scott Hanselman interviews him on Hanselminutes podcast 195.

General rules when working with Wix 3.5 in a Visual Studio 2010 environment.

a) Always use the latest version of Wix 3.5. (At the moment the latest version is 3.5.1916)
b) Wix functionality is not completely extensive and very often requires the user to develop a "custom action" to achieve the required goal.
c) Never make any changes to the MS Build or Wix target files. Attempting such a feat will put you in a world of pain.
d) Make note of where the new Wix target files are located. All VS 2010 Wix project files need to reference the Wix2010.targets file.
e) Wix 3.0 and 3.5 cannot run side by side on the same server. Upgrading Wix 3.0 to Wix 3.5 is a one way street.
f)  Upgrading a solution from VS2008 to VS2010 will require you to upgrade Wix 3.0 to Wix 3.5 and will thus require you to manually edit each Wix project file and update the target file references in all of the wix project files (wixproj) referenced by the solution.

<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.5\Wix2010.targets</WixTargetsPath>
<WixToolPath>$(ProgramFiles)\Windows Installer XML v3.5\bin\</WixToolPath>

g) There is a bug with Visual Studio 2010 whereby Wix projects are automatically checked out if you edit a Wix XML file (.wxs). Hopefully this will be patched up with Visual Studio SP1.
h) There is no single location for Wix documentation unfortunately. My next blog post will include all the useful internet links that contained information about Wix and MSBuild.

Issues experienced with the Wix installation:

1)      Wix Merge module built after the installer thus causing the installer to fail. This was a bug with the Light.exe wix command line utility which linked Wix projects.

C:\Program Files\Windows Installer XML v3.5\bin\Light.exe ... error LGHT0129: Cannot open the merge module 'XXX' from file

'XXX.msm'.

The command exited with code 129.

Done executing task "Light" -- FAILED.

Done building target "Link" in project "YYY.wixproj" -- FAILED.

 

The bug has been “documented” here:

http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Problem-with-build-order-under-MSBuild-4-0-td4903964.html

 

2)      Ensure that you have an output path declared in your Wix project (.wixproj) file.

 <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

    <OutputPath>

                XXX

    </OutputPath>

otherwise the build will fail with:

 

heat.exe : error HEAT5313: Build error during harvesting: C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets(425,7): The OutputPath property is not set for this project.  Please check to make sure that you have specified a valid Configuration/Platform combination.  Configuration='Release'  Platform='AnyCPU'

[YYY.wixproj]

heat.exe : error HEAT5307: Build failed. [YYY.wixproj]

The command exited with code 5307.

Done executing task "HeatProject" -- FAILED.

Done building target "HarvestProjects" in project "YYY.wixproj" -- FAILED.

Target "_CheckForCompileAndLinkOutputs" in file "C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets" from project

3)      This is quite obvious but ensure that all your Wix extension projects (i.e. those which use the wix.dll) have been deployed to the Wix target bin folder(C:\Program Files\Windows Installer XML v3.5\bin) otherwise you will receive the following error:

candle.exe : error CNDL0144: The extension 'C:\Program Files\Windows Installer XML v3.5\bin\XXXWixExtension.dll' could not be loaded because of the following reason: Could not load file or assembly 'file:///C:\Program Files\Windows Installer XML v3.5\bin\XXXWixExtension.dll' or one of its dependencies. The system cannot find the file specified. [YYY.wixproj]

The command exited with code 144.

Done executing task "Candle" -- FAILED.

Done building target "Compile" in project "YYY.wixproj" -- FAILED.

Target "_CheckForCompileAndLinkOutputs" in file "C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets" from project "YYY.wixproj" (target "_CleanGetCurrentAndPriorFileWrites" depends on it):

Task "CreateItem" skipped, due to false condition; (Exists('%(FullPath)')) was evaluated as (Exists('')).

Task "CreateItem" skipped, due to false condition; (Exists('%(FullPath)')) was evaluated as (Exists('XXX.msi')).

 

Visual Studio IDE bugs relating to which have now been resolved with the latest version of Wix:

a)      Custom actions project type was missing in Wix3.5 1419. This led me to believe that a normal C# library which references the Microsoft.Deployment.WindowsInstaller library would suffice as a custom action library which unfortunately is NOT the case. Upgrading to Wix Version 3.5.1916 fixes this problem.


b)      Make sure you specify Mixed platforms as the active solution platform for the solution which Team Foundation Build will be using. Configuration manager can be found in Visual Studio under Build --> Configuration Manager.

 

Hope this helps all the Wixers out there...

 

Interesting Finds - 04/07/2010

New features in MVC2
http://www.asp.net/learn/whitepapers/what-is-new-in-aspnet-mvc

ASP.Net MVC architecture Video by Rob Connery
http://www.asp.net/mvc/videos/what-is-aspnet-mvc-80-minute-technical-video-for-developers-building-nerddinner

DevExpress Asp.Net MVC extensions
http://mvc.devexpress.com/GridView/Scrolling

DevExpress online demos
http://www.devexpress.com/Downloads/NET/OnlineDemos.xml

DevExpress MVC controls integration Video
http://tv.devexpress.com/#MVCsupport.movie

Great blog post by Mr Hanselman on ASP.NET Webforms / MVC hybrids
http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx

Great blog post with source code on how to use Velocity with an ASP.NET applicatoin
http://cgeers.wordpress.com/2010/07/04/windows-server-appfabric-caching/

Great articles to read:

Scott Mitchell - LinqToXml
http://www.4guysfromrolla.com/articles/062310-1.aspx

Scott Guthrie - The new View Engine for ASP.NET
http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx

Cool article on the MVC contrib grid which has column sorting!
http://www.codecapers.com/post/Looking-for-an-MVC-Grid-Control-Try-MVC-Contrib!.aspx

Latest Version of StyleCop 4.4.0
http://stylecop.codeplex.com/releases/view/44839

The electric cool-aid acid test by Rob Connerty. A good talk about keeping an open mind. :-)
http://66.29.219.11/conery_ndc_talk.mp4

Posted by jean
Filed under:

WCF NetTcpBinding ProtectionLevel security performance test

Normally within 3 Tier applications that leverage the NetTcpBinding behind a firewall within an intranet environment I prefer to switch off security altogether since this is a trusted network zone and performace should be maximised in this case. There are times when this environment may not be trusted in which case you will need to start tweeking the relevant WCF security settings. Understanding the performance ramifications when enabling security is very important in my opinion. I was recently interested in the ProtectionLevel security setting which can be set imperatively or declaratively... so I knocked up the following performace test to see what the different performace ramifications are for the three possible options relating to ProtectionLevel.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel;

using System.Net.Security;

using System.Diagnostics;

 

namespace ConsoleApplication1

{

    //This is the minimum protection level that the binding must comply with.

    [ServiceContract(ProtectionLevel = ProtectionLevel.None)]

    public interface IConvertString

    {

        [OperationContract]

        string ConvertString(string input);

    }

 

    // Simple service which reverses a string and returns the result

    public class ConvertStringService : IConvertString

    {

        #region IConvertString Members

 

        public string ConvertString(string input)

        {

            char[] chars = input.ToCharArray();

            chars.Reverse<char>();

            return chars.ToString();

        }

 

        #endregion

    }

 

    class Program

    {

        // Setup the Service host

        private static ServiceHost StartServer<T>(string Uri, NetTcpBinding binding)

        {

            Uri uri = new Uri(Uri);

 

            ServiceHost host = new ServiceHost(typeof(ConvertStringService));

            host.AddServiceEndpoint(typeof(T), binding, uri);

            host.Open();

 

            Console.WriteLine("Service opened using NetTcpBinding with {0} protection level.", Enum.GetName(typeof(ProtectionLevel), binding.Security.Transport.ProtectionLevel));

 

            return host;

        }

 

        // Create channel using NetTcp binding with Uri and execute performance test.

        private static double RunPerformanceTestOnNetTcpBinding(NetTcpBinding binding, string endpointUri)

        {

            const int iterations = 300;

            const string stringToConvert = "12";

 

            Stopwatch watch = new Stopwatch();

            watch.Start();

            for (Int32 i = 0; i < iterations; i++)

            {

                ChannelFactory<IConvertString>.CreateChannel(binding,

                    new EndpointAddress(endpointUri))

                    .ConvertString(stringToConvert);

            }

            watch.Stop();

 

            Console.WriteLine("ConvertString with ProtectionLevel {2} : {0} times; Time taken : {1} ",

                iterations.ToString(),

                watch.Elapsed.TotalSeconds.ToString(),

                Enum.GetName(typeof(ProtectionLevel), binding.Security.Transport.ProtectionLevel));

 

            return watch.Elapsed.TotalSeconds;

 

        }

 

        static void Main(string[] args)

        {

 

            string uri = "net.tcp://localhost:7000/IConvertString";

 

            NetTcpBinding bindingNoEncryption = new NetTcpBinding();

            bindingNoEncryption.Security.Mode = SecurityMode.Transport;

            bindingNoEncryption.Security.Transport.ProtectionLevel = ProtectionLevel.None;

 

            NetTcpBinding bindingWithSign = new NetTcpBinding();

            bindingWithSign.Security.Mode = SecurityMode.Transport;

            bindingWithSign.Security.Transport.ProtectionLevel = ProtectionLevel.Sign;

 

            NetTcpBinding bindingWithEncryption = new NetTcpBinding();

            bindingWithEncryption.Security.Mode = SecurityMode.Transport;

            bindingWithEncryption.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

 

            Console.WriteLine("Run performance test or press q to Quit...");

            while (Console.ReadLine() != "q")

            {

 

                double noEncryptionTime;

                double signTime;

                double encryptionTime;

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingNoEncryption))

                {

 

                    noEncryptionTime = RunPerformanceTestOnNetTcpBinding(bindingNoEncryption, uri);

                    host.Close();

                }

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingWithSign))

                {

                    signTime = RunPerformanceTestOnNetTcpBinding(bindingWithSign, uri);

                    host.Close();

                }

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingWithEncryption))

                {

                    encryptionTime = RunPerformanceTestOnNetTcpBinding(bindingWithEncryption, uri);

                    host.Close();

                }

 

                Console.WriteLine("Run performance test again or press 'q' to Quit...");

 

           }

 

        }

 

    }

 

}

 

The results from my performance test were interesting.... see below:

 

As you can see from the above tests the when using Transport security with the NetTcpBinding ProtectionLevel Sign performance is not much different to EncryptAndSign, although there is a definite performance increase when using Protection Level None.

Additional resources:

Understanding Protection Level

 

Posted by jean
Filed under:

Using Rx for Event subscription

I thought I would have a quick look to determine wether Rx would create a strong reference under the hood or not when one object subscribed to another objects events. In this case the Consumer object subscribes to the SampleData objects's SampleDataChanged event. This type of strong reference causes memory leaks in applications because the garbage collector will not clean up the event consumer even though the consumer may be out of scope. The result of my testing indicates that unfortunately there is still a strong reference because once the Consumer object goes out of scope and once Garbage collection has been called, calling the event on SampleData still causes the event to be raised in the Consumer meaning that the consumer has not been garbage collected. Can I use the System.WeakReference object to resolve this issue? I will follow up on this shortly...


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace WeakReferenceTestConsole

{

    class Program

    {

 

        static void Main(string[] args)

        {

 

            SampleData sampleData = new SampleData();

 

            for (int i = 0; i < 3; i++)

            {

                WorkOnData(sampleData, i);

            }

 

            sampleData.RaiseSampleDataChanged("Sample Data change - Consumer outside scope");

 

            // Force garbage collection

            GC.Collect();

            GC.WaitForPendingFinalizers();

 

            sampleData.RaiseSampleDataChanged("Sample Data change - Consumer outside scope - After garbage collection");

 

            Console.ReadKey();

        }

 

        private static void WorkOnData(SampleData sampleData, int iteration)

        {

            // Create a consumer which registers a method with the sample data objects SampleDataChanged event

            Consumer consumer = new Consumer(sampleData);

            consumer.Name = "Consumer " + iteration.ToString();

 

            //Raise the sample data object's data changed event

            sampleData.RaiseSampleDataChanged("Work on data - iteration : " + iteration.ToString());

        }

 

    }

 

    public class Consumer

    {

 

        //private SampleData _sampleData;

 

        public Consumer(SampleData sampleData)

        {

            //_sampleData = sampleData;

            //sampleData.SampleDataChanged += new SampleData.SampleDataChangedEventHandler(Consumer_SampleDataChanged);

 

            Observable.FromEvent<SampleDataChangedEventArgs>(sampleData, "SampleDataChanged").Subscribe(

                args =>

                Consumer_SampleDataChanged(sampleData, (SampleDataChangedEventArgs)args.EventArgs)

                );

 

        }

 

        public string Name { get; set; }

 

        void Consumer_SampleDataChanged(object sender, SampleDataChangedEventArgs e)

        {

            Console.WriteLine("Sample Data Changed : {0} - Notified Consumer : {1}", e.Message, this.Name);

        }

 

        ~Consumer()

        {

            Console.WriteLine("Consumer finalizer");

        }

    }

 

    public class SampleData

    {

        public event SampleDataChangedEventHandler SampleDataChanged;

        public delegate void SampleDataChangedEventHandler(object sender, SampleDataChangedEventArgs e);

 

        public void RaiseSampleDataChanged(string message)

        {

            SampleDataChangedEventHandler handler = SampleDataChanged;

 

            if (handler != null)

            {

 

                SampleDataChangedEventArgs e = new SampleDataChangedEventArgs(message);

                SampleDataChanged(this, e);

            }

 

        }

 

    }

 

    public class SampleDataChangedEventArgs : EventArgs

    {

        public SampleDataChangedEventArgs(string message)

        {

            this.Message = message;

        }

 

        public string Message { get; set; }

    }

 

 

}

 

 

 

The enemy within. A bleak view into the lack of regulation in the IT industry.

“I value simplicity over everything; I always look for simplicity.”

 Anders Hejlsberg quote

As a programmer I love writing code. Make no mistake. I love flexing my mind and seeing if I can find a short and elegant route to the solution required to resolve a problem or satisfy a business requirement. The key words in that sentence are "short" and "elegant". What I mean by those words are that I prefer the fewest lines of code possible and I feel a strong need to leverage the available technologies in the most efficient and effective manner possible. Since I am a C# programmer, "efficient" means selecting the necessary 3rd party libraries or preferably using the standard libraries that come with the .Net framework that provide acceptable performance. "Effective" meaning they solve the problem in a way that produces the minimum amount of technical debt.

My favourite saying has always been "The only thing I enjoy more than writing code ... is deleting code." What I mean by this is that when I approach a legacy application in order to make changes to it or to update the functionality I keep a keen eye on attempting to identify the areas where I can delete unnecessary code.

This includes:

a) Code that has been is duplicated, not properly encapsulated into re-usable units.

b) Identifying areas where the wheel has been re-invented. An API or set of tools/libraries already existed that do the job in a more elegant (and probably more efficient) manner.

c) Identifying areas where there are unnecessary abstractions or layers of indirection.

I firmly believe that it is our duty as programmers to build maintainable and scalable applications which minimize the level of complexity within the code we write. By managing the complexity within the code we write we are able to handle and thus implement more complex business rules. This leads me onto the main reason for this blog post... The problem is that programmers admire complexity and sometimes over complicate solutions to gain "intellectual control" over the code they produce. The more difficult or complex a solution the more likely the business will develop a dependency on the developer that built that solution to maintain that solution, since they understand the solution the best and would require the least amount of time to make bug fixes or updates to the code. Management are unable to identify code that has been made to be unnecessarily complex, and when they do they are presented with reasons such as "The solution is re-usable" or "We might need that functionality for scenario A...", and needless to say scenario A is as inevitable as being hit by a meteorite.... Possible but highly unlikely.

At the moment the IT industry is suffering from the following symptoms:

1) Legacy systems that have been difficult to maintain and are undocumented.

2) Having developers take control of the core of the business by becoming dependent on the custom in house Software built to run the business.

3) Having no control mechanisms in place that will review code written by the developers.

As Billy Hollis rightly states we are all code addicts as programmers, and we need to fight this code addiction. We the programmers must avoid becoming the enemy within the organization and ensure our code is maintainable and well documented. I will attempt to provide a set of processes which management can put in place to avoid the symptoms mentioned above.

Posted by jean
Filed under:

Interesting finds - 24 May 2010

Great Ildasm.exe tutorial from MSDN
http://msdn.microsoft.com/en-us/library/aa309387(v=VS.71).aspx

Rx Extensions - Good blog post by Haacked.
http://haacked.com/archive/2010/03/26/enumerating-future.aspx

Eugene Prystupa's Blog: - Short simple and powerful ideas regarding Rx, Serialization, and MVVM
http://eprystupa.wordpress.com/

Matt Hidinger's Blog - Great MVC / Unit Testing / Entity Framework T4 Template posts

http://feeds.feedburner.com/mhidinger

AutoIT Great UI automation testing tool

http://www.autoitscript.com/autoit3/downloads.shtml

Nicolas Allen's blog - Great resource for those interested in WCF
http://blogs.msdn.com/drnick/pages/technologies-of-interest-to-wcf-developers.aspx

Linq To Xml Overview
http://msdn.microsoft.com/en-us/library/bb308960.aspx#xlinqoverview_topic2g
http://msdn.microsoft.com/en-us/library/bb387098(v=VS.100).aspx

Introduction to WPF
http://msdn.microsoft.com/en-us/library/aa970268(v=VS.100).aspx

Introduction to databinding in WPF
http://msdn.microsoft.com/en-us/library/ms752347.aspx

Posted by jean
Filed under:

Loading and executing .Net code from an external file dynamically

I've recently been tasked with writing a service which will allow me to dynamically load code from a file and inject it into an assembly at run-time for execution. The injected code will need to implement the IXmlQueryService interface. The input stream will contain the original Xml and the output stream will contain the enriched Xml. Linq to Xml is used to update the Xml from the input stream and write out the results to the output stream.

[XmlEnrichmentService.cs]

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml.Linq;

using System.Xml;

 

namespace XmlEnrichmentTestConsole

{

    // This is the code which is injected into the application at run-time

    public class XmlEnrichmentService : IXmlEnrichmentService

    {

        #region IXmlEnrichmentService Members

 

        public void EnrichXml(TextReader inputXmlStream, TextWriter outputXmlStream)

        {

            // Load the XML into the Xdocument object

            XDocument purchaseOrder = XDocument.Parse(inputXmlStream.ReadToEnd());

 

            // Extract the nodes you are interested in using Linq To Xml

            List<XElement> partNos =

                    (from item in purchaseOrder.Descendants("Item")

                     where (int)item.Element("Quantity") *

                         (decimal)item.Element("USPrice") > 100

                     orderby (string)item.Element("PartNumber")

                     select item).ToList();

 

            // Add the enrichment data

            partNos.ForEach(xElem =>

            {

                xElem.Add(new XElement("newElement",

                                new XElement("newElementChild1", "ENRICHMENT DATA")));

            });

 

            // Write the enriched XML to the output stream

            outputXmlStream.Write(purchaseOrder.ToString());

 

            outputXmlStream.Flush();

        }

 

        #endregion

    }

}


The CodeDomProvider will be used to compile and generate the assembly containing the XmlEnrichmentService.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using System.IO;

using System.Reflection;

using System.CodeDom.Compiler;

 

using Microsoft.CSharp;

using Microsoft.VisualBasic;

using System.Collections;

 

namespace XmlEnrichmentTestConsole

{

 

    public interface IXmlEnrichmentService

    {

        void EnrichXml(TextReader inputXmlStream, TextWriter outputXmlStream);

    }

 

    public class TestLoader

    {

 

        public static void TestXmlEnrichment()

        {

            using (StreamReader inputXmlStream = new StreamReader(@"CodeCompiler/PurchaseOrder.xml", Encoding.Default))

            {

                using (StreamWriter outputXmlStream = new StreamWriter(@"d:\temp\EnrichedPurchaseOrder.xml", false))

                {

 

                    StreamReader enrichmentCodeStream = new StreamReader(@"CodeCompiler/XmlEnrichmentService.cs");

 

                    CodeDomProvider codeCompiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v3.5" } });

 

                    CompilerParameters compilerParameters = new CompilerParameters();

                    compilerParameters.GenerateExecutable = false;

                    compilerParameters.GenerateInMemory = false;

                    compilerParameters.WarningLevel = 3;

                    compilerParameters.TreatWarningsAsErrors = false;

                    compilerParameters.CompilerOptions = "/optimize";

 

                    var assemblyNames = (from assembly in AppDomain.CurrentDomain.GetAssemblies()

                                         select new { Name = assembly.GetName().Name, Location = assembly.Location }).ToList();

 

                    // Extract the current domain's referenced assemblies

                    assemblyNames.ForEach(assembly => compilerParameters.ReferencedAssemblies.Add(assembly.Location));

 

                    // Compile the external source code file

                    CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource(compilerParameters, enrichmentCodeStream.ReadToEnd());

 

                    // Display compiler error results if there are any

                    if (compilerResults.Errors.HasErrors)

                    {

                        foreach (string line in compilerResults.Output)

                        {

                            Console.WriteLine(line);

                        }

                        return;

                    }

 

                    Assembly assemblyToLoad = Assembly.LoadFrom(compilerResults.PathToAssembly);

 

                    Type enrichmentServiceType = (from lt in assemblyToLoad.GetTypes()

                                                  where lt.GetInterface(typeof(IXmlEnrichmentService).Name) != null

                                                  select lt).SingleOrDefault();

 

                    if (enrichmentServiceType == null)

                        throw new NullReferenceException("Xml Enrichment Service could not be found.");

 

                    IXmlEnrichmentService enrichmentService = (IXmlEnrichmentService)Activator.CreateInstance(enrichmentServiceType);

 

                    try

                    {

                        enrichmentService.EnrichXml(inputXmlStream, outputXmlStream);

                    }

                    catch (Exception exception)

                    {

                        throw exception;

                    }

 

                }

            }

        }

 

 

    }

}


The generated  assembly is then loaded using Assembly.LoadFrom from the compilerResults.PathToAssembly and then Linq is used to discover the class which implements the IXmlEnrichmentService.

Posted by jean

Reactive Extensions for .NET (Rx) : Resources

I have recently started playing with the new Rx Extension Libraries for .net. These extensions provide the programmer with a new model for event subscription where by we can write a linq statement to query a future set of events. The power from this model is that code for event subscription is more clear AND events are handled in an asynchronous manner within the subscriber. A set of Rx extension libraries have also been made available to Java Script programmers.

The IEnumerable's counterpart is the IObserverable and the IEnumerator's counterpart is the IObserver. See below...

public interface IObservable<T>

{

  IDisposable Subscribe(IObserver<T> observer);

}

public interface IObserver<T>

{

  void OnNext(T value);

  void OnCompleted();

  void OnError(Exception exception);

}

Resources:

DevLabs: The main site where you can download the Rx Assemblies
http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

DevLabs Forums : General up to date information from the Rx community
http://social.msdn.microsoft.com/Forums/en-US/rx/threads

Rx Wiki : A good source of example code and information.
http://rxwiki.wikidot.com/

Channel9
http://channel9.msdn.com/tags/Reactive+Framework/
http://channel9.msdn.com/tags/Rx/
http://channel9.msdn.com/tags/Reactive+Extensions/

Blogs
http://mnajder.blogspot.com/search/label/Rx
http://weblogs.asp.net/sweinstein/archive/tags/RX/default.aspx
http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html
http://codebetter.com/blogs/matthew.podwysocki/archive/2009/10/14/introducing-the-reactive-framework-part-i.aspx

Posted by jean

Interesting Finds - 9 May 2010

OData - The official team blog
http://blogs.msdn.com/astoriateam/archive/2010/03/16/announcing-the-odata-sdk.aspx

Great channel 9 video on WPF development / Southridge starterkit download information
(Datagrid / WPF Ribbon)
http://channel9.msdn.com/pdc2008/PC45/

Marcin Nadjer Reactive extensions Blog (This guy knows his stuff ;-))
http://mnajder.blogspot.com/search/label/Rx

Great blog post on WPF 4 and New WPF controls by the one and only Scott Gu
http://weblogs.asp.net/scottgu/archive/2009/10/26/wpf-4-vs-2010-and-net-4-0-series.aspx

Southridge lab codeplex download location. + Links to wpf ribbon download location.
http://wpf.codeplex.com/releases/view/14962
http://www.codeplex.com/wikipage?ProjectName=wpf&title=WPF%20Ribbon%20Preview

Official Ribbon control walkthrough
http://windowsclient.net/wpf/wpf35/wpf-35sp1-ribbon-walkthrough.aspx

Unity 2.0 framework download location
http://unity.codeplex.com/

Gregory Melnik's blog - Enterprise library 5.0 / Unity 2.0 information
http://blogs.msdn.com/agile/default.aspx

Enterprise Library 5.0 download location on codeplex
http://entlib.codeplex.com/

General:
Global Visas complaints board
http://www.complaintsboard.com/complaints/global-visas-c163585.html

Posted by jean
Filed under:

Global Visas UK - Fraud

I have recently had a bad experience with a company called Global Visas here in the UK. My fiance and I approached Global Visas hoping to learn what it would entail to obtain a particular Visa.

The following set of events occurred:

1) I phoned global visas and requested information what was required to kick off the Visa application process.
I got put through to an "agent" who said I needed to open a case at the cost of 100£ and my case would be put forward to a "case worker".
I handed over my debit card details and they deducted 100£.

2) The agent then sent through a set of documents one of them being the "Client Care Letter". Without having read the documentation I proceeded to make an appointment with a case worker to determine what the Visa application process would entail, and to discuss fees.

3) During the consultation the case worker gave me no indication that by the mere fact that I was attending the consultation and had paid the £100 that the process had already been kicked off and that I was liable for the full amount of approximately £1800.

I had at no point read the client care letter even or even verbally given my approval to kick off the Visa application process. I had signed nothing either. I was completely unaware that according to them I had kicked off the Visa application process, and Global Visas made no effort to inform me at any point. I went on holiday with my fiance and after returning I noticed that an amount of approximately £700 had been deducted from my debit card without my consent. After attempting to reach my Case worker I managed to get through to the Agent (Bosco) who I initially spoke to and asked him why the money had been deducted from my account. His reaction was aggressive and completely unsympathetic and continued to accuse me of using Global Visa's services without intent to pay.

Global Visas has deducted the £700 installment from my account using the Visa debit card details they had initially obtained from my £100 fee payment. They had illegally held on to my debit card details without my knowledge or consent.

They gave me no indication that the first installment of £700 would be deducted after our initial consultation and my fiance and I
explicitly indicated that we were not sure whether we would even be applying for the Visa's at all.

By deducting the initial service fee from my account without proper consent I felt that Global Visas had unlawfully executed the
transaction for the initial fee in an attempt to tie us in to the contract. I then continued to raise a "Visa Dispute" with my bank and have been refunded the amount which was deducted by Global Visas. Through further investigation on the internet I realized that Global Visas has a name for doing such things.

A similar complaint about Global Visas UK:
http://www.complaintsboard.com/complaints/global-visas-c259741.html

The office of immigration which regulates Global Visas:

http://www.oisc.gov.uk/complaints_about_immigration_advice/


I discovered the following information in the "Client Care letter":

"After we have given you all the information and advice we can during our consultation process, you must pay our fees in full.  In line with best practice and the DSR, you are entitled to cancel this agreement up to the point where we start to provide our expert information and you accept these conditions when you pay our fees. 

Once we have provided you with our knowledge during our consultation process our full fees are payable.  As part of our service and commitment to you we are happy to assist with the following services:

You may end this contract at any time by writing to us to tell us that you are ending your agreement. But you will be legally responsible for paying any money you owe us for our fees or extra fees. You will have to pay this money even if we have asked for any of these fees at the time you end this agreement."

This is how Global Visas bully you into a contract with them.

Posted by jean
Filed under: ,

Find a user's Active Directory groups.

I like simple solutions. Fortunately the .Net Framework API's are slowly evolving to make life simpler for the architect and programmer. One new .Net 3.5 framework library which I am very happy with is System.DirectoryServices.AccountManagement. Have a look at how simple it is to find the groups an AD user belongs to.

Add a reference to System.DirectoryServices and System.DirectoryServices.AccountManagement.

 

using System;
using System.Collections.Generic;
using System.Linq;

using System.DirectoryServices.AccountManagement;

namespace DetermineUserGroupsConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            //Initializes a new instance of the System.DirectoryServices.AccountManagement.PrincipalContext
            //class with the specified context type.
            PrincipalContext principalContext = new PrincipalContext(ContextType.Machine);
            UserPrincipal userPrinciple = UserPrincipal.FindByIdentity(principalContext, IdentityType.Name, "EHS\\jean");

            // Select a list of group names from the PrincipalSearchResult<Principal>
            var userGroups = from userGroup in userPrinciple.GetGroups()
                             select userGroup.Name;
            
            foreach (string groupName in userGroups)
            {
                System.Console.WriteLine(groupName);
            }

            System.Console.ReadKey();
        }
    }
}

 

Have a look at the MSDN site or codeproject for further information on this topic.

Hope this was helpfull. 

Posted by jean
Filed under:

Interesting finds - 15 April 2010

Security: 

Some great security code examples entailing encrypting and decrypting messages and files compliments of Channel 9.
http://channel9.msdn.com/Wiki/SecurityWiki/CodeExamples/

Euler:

Depth First Search Algorithm for Tree Data structures
http://en.wikipedia.org/wiki/Depth-first_search

Project Euler solution for top to bottom summing in tree data structures
http://blog.singhanuvrat.com/problems/project-euler-maximum-sum-traversing-top-to-bottom-in-a-triangle

Visual Studio 2008 Web deployment projects – Very useful when publishing a Web project in VS 2008
http://blogs.msdn.com/webdevtools/archive/2008/01/25/announcing-rtw-of-visual-studio-2008-web-deployment-projects-wdp.aspx
http://weblogs.asp.net/scottgu/archive/2008/01/28/vs-2008-web-deployment-project-support-released.aspx
Download at: http://www.microsoft.com/downloads/details.aspx?FamilyId=0AA30AE8-C73B-4BDD-BB1B-FE697256C459&displaylang=en

Slides for Continuous integration using VS 2010 : This can be used as a reference to find additional material.
http://www.slideshare.net/clintedmonson/drive-your-development-with-visual-studio-2010

Mix 2010 Session Videos – Awesome videos on the latest and greatest web technologies from Microsoft
http://live.visitmix.com/Videos

JQuery ExtJs Framework – Pricey but impressive
https://www.extjs.com/deploy/dev/examples/desktop/desktop.html

Tools:

FileZilla ; Great tool for testing SFTP connections or transferring files over FTP/SFTP.
http://filezilla-project.org/

General:

Good link for working out monthly, weekly and daily wages
http://listentotaxman.com/index.php

Good link for beginners of Linq

http://net.tutsplus.com/tutorials/asp-net/net-linq-from-scratch/

Posted by jean
Filed under:

Interesting finds - 8 April 2010

I sometimes find that surfing the internet results in information overload. I end up with 20 open tabs in Chrome, a double Latte at my side and not enough time to investigate all my "interesting finds". So I've decided to post my finds in a similar manner to Jason Haley's blog so that I may reference them at a later date and share them with you at the same time. :-)

ASP.NET:

Custom paging with the Repeater Control and the PagedDataSource
http://www.dotnetcurry.com/ShowArticle.aspx?ID=345&AspxAutoDetectCookieSupport=1

VS 2010 & .Net 4.0

VS 2010 and .Net 4.0 Training Kit - Webcasts and source code for the latest version of VS and .Net
http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=752cb725-969b-4732-a383-ed5740f02e93&displayLang=en

WPF:

Good WPF resource for begginers
http://en.csharp-online.net/WPF_Concepts%E2%80%94Property_Value_Inheritance

 Entity Framework:

Rob Bagby's Entity Framework posts. Good resource for Begginers
http://www.robbagby.com/entity-framework/entity-framework-series-index/

Oleg Sych's Blog : Entity Framework Tools in Visual Studio and the T4 Template Toolbox
http://www.olegsych.com/2009/12/simplifying-entity-framework-data-driven-design/

Security:

Claims based single-signon for the web. [Strategies for migrating your systems to Microsoft Windows Azure]
http://msdn.microsoft.com/en-us/library/ff359102.aspx

General knowledge:

Concept of Covariance and Contravariance in .net 4.0
http://www.codedigest.com/Articles/Framework/300_The_concept_of_Covariance_and_Contravariance_in_Net_40.aspx

Programming Algorithms and Data Structures
http://msdn.microsoft.com/en-us/vcsharp/aa336800.aspx

Investigating the History of .Net
http://www.itwriting.com/dotnet2.php#problems

Charles Petzold's .Net Book Zero online and free
http://www.charlespetzold.com/dotnet/index.html

Channel 9 Pex in VS 2008
http://channel9.msdn.com/posts/Peli/Getting-started-with-Pex-in-Visual-Studio-2008/

Posted by jean
Filed under:

Superman's alter ego - Quintin Tarantino's analogy

Here is a small section of the Kill Bill script that I enjoyed very much. In true Tarantino story telling style, Tarantino analyses superman's alter ego and makes a few interesting deductions.

"...l'm quite keen on comic books.

Especially the ones about superheroes.

I find the whole mythology
surrounding super heroes fascinating.
                   
Take my favorite super hero, Superman.
                   
Not a great comic book.
Not particularly well-drawn.
                   
But the mythology...
                   
The mythology is not only great,
it's unique.
                   
[...]

                 
Now, a staple of the superhero
mythology is,
                   
there's the superhero
and there's the alter ego.

Batman is actually Bruce Wayne,
Spider-Man is actually Peter Parker.
                   
When that character wakes up
in the morning, he's Peter Parker.
                   
He has to put on a costume
to become Spider-Man.
                   
And it is in that characteristic
Superman stands alone.
                   
Superman didn't become Superman.
                   
Superman was born Superman.
                   
When Superman wakes up
in the morning, he's Superman.
                   
His alter ego is Clark Kent.
                   
His outfit with the big red "S" -
                   
that's the blanket he was wrapped in
as a baby when the Kents found him.
                   
Those are his clothes.
                   
What Kent wears - the glasses,
the business suit - that's the costume.
                   
That's the costume Superman wears
to blend in with us.
                   
Clark Kent is how Superman views us.
                   
And what are the characteristics
of Clark Kent?
                   
He's weak...
...he's unsure of himself...
...he's a coward.
                   
Clark Kent is Superman's critique
on the whole human race. "

Personally I believe Superman chose a weak alter ego to mask his power... but thats just my less interesting viewpoint ;-)

 

Posted by jean
More Posts Next page »