Monday, February 25, 2013

Working with bunch of items in small chunks using yield

Sometimes, we found ourselves in situations we we have to deal with large bunch of items and the code we are dealing with is unable to work with single large list. We then break large list into small chunks and process these chunks one by one. I found myself in such situations couple of times recently. So I decided to write some code which is efficient and is reusable.

Yield is a very useful keyword when worked with a collections. I used this to write an  extension method which takes a collection  and size of subset, split the collection into even sized small subsets and then return each subset one by one.

Here is my code,

  1. public static IEnumerable<IEnumerable<T>>
  2.         Subset<T>(this IEnumerable<T> list, int size)
  3.         {
  4.             int subset = 0;
  5.             do
  6.             {
  7.                 yield return list
  8.                     .Skip((subset++)*size)
  9.                     .Take(size);
  10.             } while (subset * size < list.Count());
  11.         }

Sunday, March 20, 2011

WCF Basic Authentication:Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.

I was testing the service to authenticate users with basic authentication over http (not https). To Achieve this, I used basicHttpBinding as binding and configured it for TransportClientCredentialOnly security mode.

<basicHttpBinding> 
<binding name="http_transport_basic">
<security mode="TransportCredentialOnly">
<transport clientCredentialType ="Basic"/>
</security>
</binding>
</basicHttpBinding>



Everything was looking good so far until I hit the f5 to visit the familiar yellow error page complaining about InvalidMexHttpPoint


But why. I am using basic authentication and basic authentication is enabled in the IIS. Thanx to the Mapelli for the post which points the cause of the problem. I removed the mex point and hit F5 again. There is no more error page. But now the question arises, Is there any way to include the mex point?. Answer is yes. I just replaced the mex binding from  “mexHttpBinding” to basicHttpBinding and created the bindingConfiguration similar to the service endpoint’s binding configuration. This change enabled me to use the mex point which is also configured for basic authentication.

WCF Error: The contract name ‘IMetadataExchange’ could not be found in the list of contracts implemented by the service

This is the most common error almost everyone receives when starts learning WCF and mostly because you have overlooked the configuration. It is easy to miss the typo mistake and specially when it is just matter of lower or upper case of a single character. We, developers, are normally used to capitalize the “D” of the “Data” and this is what we do with “IMetadataExchange” and type “IMetaDataExchange”. Remember configuration parser is case sensitive and it treats “IMetadataExchange” and “IMetaDataExchange” differently. WCF complains this typo mistake in this fashion.spelled wrong

This error clearly states that it is unable to find the contract. Now even after correcting the mistake you still can face another yellow screen of error

metadataexchangeerror

This happens because

  • You have not defined serviceMetadata behavior. Go to configuration file and add following configuration sample.
    <behaviors>
    <serviceBehaviors>
    <behavior name="default">
    <serviceMetadata httpGetEnabled="true" />
    </behavior>
    </serviceBehaviors>
    </behaviors>



  • You have defined the service behavior but have not set the service behavior configuration name. Set the behaviorConfiguration attribute of the service to the name of the service behavior you defined.
<services>
<service name="Service" behaviorConfiguration ="default">

Sunday, February 20, 2011

Amazon Route 53: .Net library is here.


At the end of the year 2010, Amazon has launched a new web service called “Amazon Route 53” which is focused on operating DNS. Addition of this web service in the stack of Amazon web service suite has made hard for the competitors to stand near the Amazon.
Amazon Route 53 is designed to be fast, easy to use, easy to program and cost effective.  An easy to use API has made it easy to integrate this service into an existing application and let you offer the UI of your own choice to your users.   
What is Amazon Route 53?
The name Amazon Route 53 comes from the fact that port 53 is used to entertain the DNS queries. According to Amazon
“Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service. It is designed to give developers and businesses an extremely reliable and cost effective way to route end users to Internet applications”.
It also provides a programmatic access to work with DNS like adding, modifying or deleting DNS records.
Amazon Route 53 and .Net
Amazon has exposed an XML  RESTful web service API for programmatic access. Dealing with the raw RESTful request and response is very much painful and prone to errors. But thanks to the WCF architecture which enables .net developers to deal with this raw data as strongly typed classes and takes care of the complicated coding part itself. But the real art is how to configure and code WCF to lessen the pain and increase the gain.
Here is my library with source code for you. Amazon.Route53 is now moved to codeplex. It is free to use.
If you find any better way to code Route 53 or any bug in my code then please let me know.

Thursday, December 16, 2010

Allow windows service to “Interact with desktop”

Typically, services are designed to run unattended without any UI with any need to interact with desktop or any GUI application. However, in some cases, it is desired to let the service show and communicate with graphical applications. Reason might be to track an already developed application and start this app if closed. Or you might want some input from user or want to alert him immediately about some serious has happened. Whatever the reason be, there is always a need to find a way to enable your service to display the GUI application in interactive windows satiation.

Solution is one click away and we only need to mark the “Allow Service to interact with desktop” as checked. But question is can we do this programmatically? If yes then how?

clip_image002

There are four ways to change the windows service options and we will discuss them one by one. But before that you need to know that to make a service interact with desktop, service

· Account type must be Local System.

· Service type must be Own Process or Shared Process.

1. Through Windows Registry

A service installed on the system has its options saved in the system registry under “System\CurrentControlSet\Services“in LocalMachine key with your service name. The name/value pair we are interested in is “type”. Its type is integer and it is equivalent to ServiceType in its value. Here is how we can do this.

   1:  var ServiceKeys = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
   2:      String.Format(@"System\CurrentControlSet\Services\{0}", ServiceName), true);
   3:  try
   4:  {
   5:   
   6:      var ServiceType = (ServiceType)(int)(ServiceKeys.GetValue("type"));
   7:   
   8:      //Service must be of type Own Process or Share Process
   9:      if (((ServiceType & ServiceType.Win32OwnProcess) != ServiceType.Win32OwnProcess)
  10:      && ((ServiceType & ServiceType.Win32ShareProcess) != ServiceType.Win32ShareProcess))
  11:      {
  12:          throw new Exception("ServiceType must be " +
  13:              "either Own Process or Shared Process to enable interact with desktop");
  14:      }
  15:      var AccountType = ServiceKeys.GetValue("ObjectName");
  16:      //Account Type must be Local System
  17:      if (String.Equals(AccountType, "LocalSystem") == false)
  18:          throw new Exception("Service account must be local system to enable interact with desktop");
  19:   
  20:      //ORing the InteractiveProcess with the existing service type
  21:      ServiceType newType = ServiceType | ServiceType.InteractiveProcess;
  22:   
  23:      ServiceKeys.SetValue("type", (int)newType);
  24:  }
  25:   
  26:  finally
  27:  {
  28:      ServiceKeys.Close();
  29:  }



This requires the system startup since registry change is not notified to Service Control Manager (SCM), change is visible in service property window though. It is because property window always load recent settings from the registry.

2. Through WMI

If you do not want to play with the registry or restart seems not a good option in your case then there is another solution for you which is WMI. WMI class WIN32_Service let you play with the windows service. This class provides a method called “Change” which allows you to modify the service. You can read more about WIN32_Service here. Here is how to do the job.

   1:  //Create a Management object for your service.
   2:  var service = new System.Management.ManagementObject(
   3:      String.Format("WIN32_Service.Name='{0}'", ServiceName));
   4:  try
   5:  {
   6:      var paramList = new object[11];
   7:      paramList[5] = true;//We only need to set DesktopInteract parameter
   8:      var output = (int)service.InvokeMethod("Change", paramList);
   9:      //if zero is returned then it means change is done.
  10:      if (output != 0)
  11:          throw new Exception(string.Format("FAILED with code {0}", output));
  12:   
  13:  }
  14:  finally
  15:  {
  16:      service.Dispose();
  17:  }



Good thing in this technique is it does not require any system reboot. Only service restart is required.

3. Through Command

SC is a command-line utility which allow managing the services. SC is available for scripting and script can be run through .net. It means we can use sc command to configure the windows service. You can see a complete list here to unleash the power of this command. For now our purpose is to enable the “Interact with desktop” option and config command is there to do this job. What we need to do is run the command through code and if output is “[SC] ChangeServiceConfig SUCCESSS” then it means our job is done. Here is how to do this

string command = String.Format("sc config {0} type= own type= interact", ServiceName);
var processInfo = new System.Diagnostics.ProcessStartInfo()
{
//Shell Command
FileName = "cmd"
,
//pass command as argument./c means carries
//out the task and then terminate the shell command
Arguments = "/c" + command
,
//To redirect The Shell command output to process stanadrd output
RedirectStandardOutput = true
,
// Now Need to create command window.
//Also we want to mimic this call as normal .net call
UseShellExecute = false
,
// Do not show command window
CreateNoWindow = true

};

var process = System.Diagnostics.Process.Start(processInfo);

var output = process.StandardOutput.ReadToEnd();
if (output.Trim().EndsWith("SUCCESS") == false)
throw new Exception(output);



4. Through interop.

Question is, do we need this when we have three nice options using managed code. For me it is useless and that’s why I am leaving it

Let me end this article with words of caution.

“Interact with Desktop” option is no more supported by Microsoft since Windows Vista. So use wisely and redesign your app if there is a solid chance that your service can be installed on vista or server 2008.

Monday, December 13, 2010

How to read memo block from FPT file.

Recently, I came across a situation where I need to extract the memo field data from an FPT file. After lot of googling I found this documentation which describes the FPT structure and then I decided to write my own code to parse the FPT file and extract the data stored in it.
A memo file (FPT) file contains one header and any number of block structures. The header part is 512 bytes long but the useful information is stored in 7th and 8th byte which is the size of the block structure.
 Following the header is the first memo block. A memo block consists of a memo block header and memo text. Memo block is 8 bytes long and stores the type of memo data and the length of the memo data.

A memo block can span over multiple blocks structures but a single block can’t have data of more than one memo block. It means if block is larger than the memo size then remaining block will be unused.
Here is the code to extract memo data.
public class MemoBlock
    {
        public MemoDataType MemoDataType { get; private set; }
        public Byte[] Memo { get; private set; }

        public MemoBlock(MemoDataType type, Byte[] data)
        {
            this.MemoDataType = type;
            this.Memo = data;
        }
    }

    public enum MemoDataType
    {
        Picture = 0
        , Text = 1
    }

    public class MemoCollection : IEnumerable<MemoBlock>
    {
        private System.IO.Stream Stream = null;
        private int blockSize = 0;

        public MemoCollection(System.IO.Stream memoStream)
        {
            this.Stream = memoStream;
        }

        #region IEnumerable<MemoBlock> Members

        public IEnumerator<MemoBlock> GetEnumerator()
        {
            return GetCollection();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        private IEnumerator<MemoBlock> GetCollection()
        {
            Stream.Seek(0, SeekOrigin.Begin);
            GetBlockSize();
            while (Stream.Position < Stream.Length)
            {
                var memo = ReadMemo();
                PositionToNextBlock();               
                yield return memo;
            }
        }

        private void PositionToNextBlock()
        {
            int unusedbytecount = (int)(Stream.Position % blockSize);
            if (unusedbytecount > 0)
                Stream.Seek(blockSize - unusedbytecount, SeekOrigin.Current);
        }

        private MemoBlock ReadMemo()
        {
            Byte[] header = new Byte[8];
            Stream.Read(header, 0, header.Length);
            MemoDataType type = (MemoDataType)ToInteger(header.Take(4).ToArray());
            int memoSize = ToInteger(header.Skip(4).Take(4).ToArray());
            Byte[] memoData = new Byte[memoSize];
            Stream.Read(memoData, 0, memoData.Length);
            return new MemoBlock(type, memoData);
            
        }

        private void GetBlockSize()
        {
            Byte[] buffer = new Byte[512];
            Stream.Read(buffer, 0, buffer.Length);
            blockSize = ToInteger(new Byte[] { 0,0,buffer[6],buffer[7]});

        }

        private int ToInteger(byte[] data)
        {
            if (BitConverter.IsLittleEndian)
                Array.Reverse(data);
            return BitConverter.ToInt32(data,0);
        }

        #endregion
    }