Category Archives: .NET

Activation error occured while trying to get instance of type Database, key “” | EntLib


The title of this post may sound a bit strange for those who have not faced this problem but it may sound a Sweet Tune Music πŸ™‚ to those who want to resolve this nasty error in their application.

If you fall into the latter category, you can directly jump to the Solution section though everybody is definitely welcomed to read the entire post.

What is this about?
An error which occurs when using Enterprise Library Data Access Block in instantiating a Database using factory approach.
You may have followed the msdn article to setup DataAccessBlock with the correct code and the configuration in your application but always resulting into the error when you try to instantiate a database object.

Context
Typically, software solutions are multi-layered. One of them being a Data Access Layer, aka DAL, which interacts with the Data Store(s) and performs the CRUD operations on the data in the data store. In this layer, you can either opt for ADO.Net or Enterprise Library Data Access Block to connect to Data Store (database) besides other options.

Since, the post is talking about a specific error resulted in the EntLib, lets assume that we preferred to implement DAL using EntLib Data Access Block.

Problem / Error
Activation error occured while trying to get instance of type Database, key “”
This error occurs on the below code statement, the very first statement to perform the CRUD operation into the DataStore.

Database dataStore = DatabaseFactory.CreateDatabase();

or,

Database dataStore = DatabaseFactory.CreateDatabase("someKey");

Cause
Enterprise library consists of number of classes in different namespaces and assemblies.
Two of them are:

  1. Microsoft.Practices.EnterpriseLibrary.Data
  2. Microsoft.Practices.EnterpriseLibrary.Common

The above code statement is present in the former assembly. After a series of function calls in the same assembly and the latter assembly, a function in the latter assembly tries to load the former assembly using the partial name.

Note: Loading of an assembly using Partial name
This is what leads to the error if the Enterprise libraries assemblies are GACed and not copied locally into the application directory.
Assembly with a partial name won’t be found in the GAC and then the search/probing of an assembly will continue to Local Application Directory or sub-directories with the same name or as per configuration.
Since assembly is not present anywhere else except GAC, assembly loading will fail and leading to this error.

You can see this in action by launching Fusion Log Viewer utility, which comes by default. Command is : “fuslogvw” in case yof could not locate the utility. Type the command in the Visual Studio Command Prompt.
You may need to customize the Log Viewer to log all binding to disks to view every log.

[You can opt to open this assembly into a Reflector or ILSpy and go through each code statement and function call post the above code statement to understand more.]

So, is there a solution or a workaround for the above problem?

Resolution
This problem is solvable. πŸ™‚
Problem can be solved in many ways, you choose what suits you the best.

  1. You can deploy the enterprise library, “Microsoft.Practices.EnterpriseLibrary.Data” locally to the applcation bin directory. [This may lead to maintaining multiple copies of the same assembly]
  2. Another option is to have the below configuration in the application configuration file. This appears a bit clean approach but again the same configuration change has to be done at multiple places if they are using this library

    <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Data" fullName="Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </assemblyBinding>
    </runtime>

    Thanks to Mr. Philippe for this 2nd solution posted @ CodePlex.
Advertisements

Task Scheduler in C#.Net


This article describes a way to create the Scheduled tasks in a system pro-grammatically for Windows Vista, Windows 7 etc Operating Systems using C#.NET language. Windows operating systems, though, already provide a User Interface to see a complete list, to add, to update or to delete a Scheduled Task under it. This UI can be seen by launching a Computer Management by issuing a command compmgmt.msc on a command prompt.

System Requirements
Windows Vista or Windows 7 or higher versions Operating systems

Development Environment

  • Development IDE – Visual Studio [or simple Notepad]
  • Task Scheduler COM Library

How to Implement?
To begin with, we need an underlying library, can be COM library or unmanaged C(++) library or managed wrapper which talks to the system to get things done.
Aaannnnnnnn.
Don’t worry.
Here is the trick.
If you dare to πŸ™‚ browse to C:\Windows\syswow64, you will notice the presence of Taskschd.dll assembly. This is what we need to proceed with.

Steps:

  1. Create a new Project using Visual Studio
  2. Right Click on project and click Add Reference.Select “TaskScheduler TypeLibrary”

The last step resulted in an Interop assembly generation and referenced in the project. You can check this by selecting a referenced assembly and viewing it’s properties.

Now, we’ll make use of Types defined/exported in the interop assembly to achieve:
– View the list of all Scheduled Tasks
– To pro-grammatically add a Scheduled Task
– To delete a task

Be it any CRUD operation, we’ll make use of ITaskService type which connects to an actual store and exposes the operations. We’ll instantiate the TaskService and call the Connect method before any valid operation.

Before detailing out the steps, another important aspect is to understand the layout or a structure, the tasks are organized.

Scheduled Tasks are organized in a hierarchical fashion. They are always stored in a folder. The very first folder is termed Root Folder with a path @”\” or “\\”. Each folder can have sub folders under it. View the above picture to understand or open “Scheduled Tasks” on your system.

The following sections detail out “How to ?” part for each operation.

How to retrieve the list of all Scheduled Tasks?

  1. Instantiate TaskService object.
    ITaskService taskService = new TaskScheduler();
  2. Call Connect() on previously created taskService object.
    taskService.Connect();
  3. Get a reference to Root Folder.
    ITaskFolder rootFolder = taskService.GetFolder(@"\");
    Remember, path to Root Folder is “\”.
  4. Make a call to GetTasks() on a folder.
    IRegisteredTaskCollection tasks = rootFolder.GetTasks(0); // 0 or 1: 1 will include all hidden tasks as well
    Note: Here, you will get those tasks only which are created in root folder. Since this root folder can have sub folders under it, you have to recursively call GetTasks() for each sub-folder.

    private void Load()
        {
            ITaskService taskService = new TaskScheduler();taskService.Connect();List tasks = new List();// β€œ\\” or @”\” is the RootFolder
            this.GetData(taskService.GetFolder(@”\”), tasks);
            this.view.ScheduledTasks = tasks;
        }
    
        private void GetData(ITaskFolder folder, List tasks)
        {
            foreach (IRegisteredTask task in folder.GetTasks(1)) // get all tasks including those which are hidden, otherwise 0
            {
                tasks.Add(task);
    
                System.Runtime.InteropServices.Marshal.ReleaseComObject(task); // release COM object
    
                foreach (ITaskFolder subFolder in folder.GetFolders(1))
                {
                    this.GetData(subFolder, tasks);
                }
            }
            System.Runtime.InteropServices.Marshal.ReleaseComObject(folder);
        }
    

How to delete a Scheduled Task?
We need some task details like task name, task container i.e. folder in which this task exists in order to delete it.
By default, each task’s Location property contains the Name of that particular task as well as it’s containing folder. So if we have an access to Task Location only, we can find out it’s name and it’s containing folder through some string manipulation.
For e.g., “\\SampleTaskFolder\\SampleTask” means that the task named SampleTask is stored in a folder SampleTaskFolder which is further in RootFolder(“\\”).
Steps to delete a task when it’s full location is provided as input:

  • Find out the name of Task and it’s containing folder through string manipulation. [You may want to Validate the input:task Location]
  • Instantiate a task service and connect
  • Get the containing folder reference through below code:
    ITaskFolder containingFolder = taskService.GetFolder(folderPath);
  • Call DeleteTask() with a task name
    containingFolder.DeleteTask(taskName, 0);

This is how a complete function may Look like:

public bool DeleteTask(string taskPath)
{
ITaskService taskService = new TaskScheduler();taskService.Connect();ValidateTaskPath(taskPath);

int lastIndex = taskPath.LastIndexOf(β€œ\\”);

string folderPath = taskPath.Substring(0, lastIndex);

if (string.IsNullOrWhiteSpace(folderPath))
{
folderPath = β€œ\\”;
}

string taskName = taskPath.Substring(lastIndex + 1);

try
{
ITaskFolder containingFolder = taskService.GetFolder(folderPath);

containingFolder.DeleteTask(taskName, 0);
}
catch(FileNotFoundException exception)
{
throw new InvalidTaskPath(β€œTask Path is invalid”, exception);
}

return true;
}


agoda.com INT

How to create\update a Scheduled task?
Creating a Scheduled task is not as easy as other operations. Before i detail out the steps here, i am pinpointing few things which are expected by COM and it’s behavior, to get our new task registered successfully in the system.

  • Name of a new Task to be created can be empty while doing registration. If this is the case, system will generate a GUID and assign this as a name of a task
  • The ExecutionTimeLimit, IdleDuration parameters under ITaskDefinition [see “Possible error and exceptions” section below] should be in a particular format. If this is not the case, new task won’t be registered
  • Atleast one action should be specified when registering a new task
  • If a task with the same name under the same folder exists, it will be updated if you register a task with a flag: “CreateOrUpdate” has a value of ‘6’. It is the 3rd argument passed in a call to RegisterTaskDefinition()

Now, let’s see how can we achieve this programmatically using C#.NET.
The below code will create\update a task under a Root Folder “\”. You may choose to create under a sub-folder.

Steps to create a task under Root Folder:

    1. Instantiate a task service and connect
      ITaskService taskService = new TaskScheduler();
    2. Create a new task using task Service object. This requires calling “taskService.NewTask(0)”

      ITaskDefinition taskDefinition = taskService.NewTask(0);
    3. Configure a new Task – all desirable properties like – Name, Description, Triggers, Actions, Author etc.

      taskDefinition.RegistrationInfo.Description = "task Description Goes Here";
      taskDefinition.RegistrationInfo.Author = "task Author domainName\userName goes here";
      taskDefinition.Settings.Enabled = “true or false”;
      taskDefinition.Settings.Hidden = “true or false”;
      taskDefinition.Settings.Compatibility = _TASK_COMPATIBILITY.TASK_COMPATIBILITY_V2_1;if (“You want to set the execution time limit for Task Actions”)
      {
      TimeSpan timespan = TimeSpan.FromMinutes(“No of minutes goes here”);// this is the format needed by COM
      taskDefinition.Settings.ExecutionTimeLimit = XmlConvert.ToString(timespan);
      }

      if (“You want to allow the task to execute only when system is idle for so many minutes”)
      {
      taskDefinition.Settings.RunOnlyIfIdle = “true or false”;

      TimeSpan timespan = TimeSpan.FromMinutes(“Number of Minutes Goes Here”);

      // this is the format needed by COM
      taskDefinition.Settings.IdleSettings.IdleDuration = XmlConvert.ToString(timespan);
      }

    4. Configure triggers, if any

      ITriggerCollection triggers = taskDefinition.Triggers;
      ITrigger trigger = triggers.Create("type of Trigger goes here"); // _TASK_TRIGGER_TYPE2 enumeration
      trigger.Enabled = "true or false";
      trigger.StartBoundary = DateTime.Now.ToString(Constants.DateTimeFormatExpectedByCOM);
      if (“You want this trigger to expire after sometime”)
      {
      trigger.EndBoundary = DateTime.Now.EndTime.ToString(Constants.DateTimeFormatExpectedByCOM);
      }
    5. Configure Actions [atleast one]

      IActionCollection actions = taskDefinition.Actions;
      _TASK_ACTION_TYPE actionType = "type of action you want goes here";
      IAction action = actions.Create(actionType);
      switch (actionType)
      {
      case _TASK_ACTION_TYPE.TASK_ACTION_EXEC:
      IExecAction execAction = action as IExecAction;execAction.Path = “Path to Program To Run goes here”;
      execAction.Arguments = “Optional Arguments goes here when starting the above executable”;
      break;case _TASK_ACTION_TYPE.TASK_ACTION_SEND_EMAIL:
      IEmailAction mailAction = action as IEmailAction;

      mailAction.From = “Sender email address goes here”;
      mailAction.To = “Receiver email address goes here”;
      mailAction.Server = “SMTPServer address goes here”;
      mailAction.Subject = “email Subject goes here” ;
      mailAction.Body = “email MessageBody goes here”;

      break;

      case _TASK_ACTION_TYPE.TASK_ACTION_SHOW_MESSAGE:
      IShowMessageAction showAction = action as IShowMessageAction;

      showAction.Title = “Display Title goes here”;
      showAction.MessageBody = “Display Message goes here”;
      break;
      }

    6. Till this point, we have configured task settings, triggers, actions, conditions. Now we need to register this task definition under some folder, RootFolder – “\”, here

      // creating this task in the root Folder
      // Create SubFolder under RootFolder, if you require
      ITaskFolder rootFolder = taskService.GetFolder(@"\");
      // ‘6’ as argument means this task can be created or updated [“CreateOrUpdate” flag]
      // if Name id empty or null, System will create a task with name as GUID
      rootFolder.RegisterTaskDefinition(task.Name, definition, 6, null, null, _TASK_LOGON_TYPE.TASK_LOGON_NONE, null);

That’s all we need to do. If luck goes with you:), you won’t get errors [not like me]. Just kidding.
If you get a new error, contact me. I’ll try to find a cause and suggest you a resolution.

Possible errors and exceptions

  • Error Code :-2147216616,
    System.Runtime.InteropServices.COMException (0x80041318): (8,44):StartBoundary:26-01-2012 08:28:31

Cause: “ExecutionTimeLimit”/ “IdleDuration” are expected in some format by COM and not just simple ToString() conversion
Resolution: Use System.Xml.XmlConvert.ToString(). [Spent lot of time to get to this]

  • System.Runtime.InteropServices.COMException (0x80041319): (38,4):Actions:

Cause: This means tat atleast one action should be specified when registering a task definition for a new task.
Simply put, a task should define atleast one action
Resolution: Specify atleast one action – be it : To send an email or To execute a task or To display a message

  • System.Runtime.InteropServices.InvalidComObjectException was caught
    Message=COM object that has been separated from its underlying RCW cannot be used.
    Source=mscorlib
    StackTrace:
    at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
    at TaskScheduler.ITaskService.get_Connected()InnerException:

Cause:
You are trying to work on the Released TaskScheduler COM object
Resolution:
Create a new object of TaskScheduler , connect and carry on with your task operation

  • Error Code: -2147221163. Interface not registered while creating a task.

Yet to identify the real cause and resolution. [Noticed this when i share the same TaskScheduler instance and use it from diferent win forms]

References

Playaround with an address of object reference variable


Well, rarely you will have to find an address of a variable in C#.NET. Though C#.NET allows use of pointers but anyone hardly use them. .NET base library and Compiler have done a beautiful job, abstracting the complex use of pointers, exposing ref, out keywords.

But what if you still want to playaround?
[I must warn you about this. Don’t dare to play with Pointers πŸ™‚ Improper handling of pointers can even bring your application down]

Thankfully, there are constructs which do help in achieving what we want.

The above link is just to get a concept of Stack. What a stack is. It has nothing to do with Stack class provided in C#.NET.

static void GetAddress()
{
unsafe
{
int i = 5;
object refer = new object();
// &i gets an address of variable 'i' and * operator gets the value
Console.WriteLine("Address of i:{0},{1}" , (uint)&i, *(&i));
Console.WriteLine("Address of refer:{0},{1}", (uint)(&i - 1), *(&i - 1));
}
}

Explanation
Here, i have defined two variables, named – i and refer . Both these variables sit on STACK, however the values stored by them are treated differently.
i stores the value directly [5 in our case as per statement], and
refer stores the address of an actual object allocated on a manged heap.
This is how Stack and Heap state would be after two initalizing statements.

So, if i have an access to an address of i and knowing that refer is on Stack just after i, decrementing 1 from i address [Pointer arithmetic], i’m now pointing to the refer which is the reference to the actual object (object()) sitting on heap.

You have a stack address and thus the value stored at that location. Using Pointer Arithmatic, do what you want WITH CARE.
MS should tag POINTERS with “HANDLE WITH UTMOST CARE” πŸ™‚

How to read or write excel file using ACE OLEDB data provider?


This article describes the way to read or write into the excel workbook(or a file, used interchangeably) pro-grammatically using C#.NET language and ACE Oledb data providers by Microsoft.
This covers the following topics:

  • System Requirements
  • Development Environment
  • Versions of Excel files which can be read or written
  • How to build a connection string?
  • How to build a command string?
  • Possible errors and exceptions

System Requirements
To read/write the excel worksheet using ACE oledb providers, MS office need not to be installed on a machine. An installable package containing ACE oledb providers can be installed from ACE OLEDB Installer Location
Go to this link to install the required version and also check the system requirements.
Note: You can install either 32 bits version or 64 bits version but not both. Also, if you have 64 bits office installed then you can’t install 32 bits ACE oledb and vice versa.
Check the requirements carefully on the page.

Continue reading How to read or write excel file using ACE OLEDB data provider?

Modify App Configuration while running application , C#.NET


Each application has it’s own configuration file, be it a windows based application or web based.
This application configuration file defines information which can be used by application to make decisions, to load some other information or may contain the custom configuration which can be empowered to do anything.
There can also be scenarios where an application may want to change\modify the existing setting in the application configuration file and those changes should not only take effect immediately but should also be persisted.

For this,
APIs are available which can load and modify the configuration despite reading.

Make use of Configuration class in System.Configuration namespace.
– Add the reference to System.Configuration to your project
– Create a function which does the following:

  • Make a call to OpenExeConfiguration() method
  • Get a reference to the section which is used by module
  • Make a call to Add\Remove or access the Value property to change the value
  • Make a call to Save() method
  • And, finally refresh the Configuration Section by calling RefreshSection() so that the next read from Config file happens by reading it from disk.

– Call the above function with proper values before invoking a method to be unit tested
– Do the clean up if required before executing another test case

Following is the code snippet which adds\changes the key-vale pair in the appSettings section of the config file:
Continue reading Modify App Configuration while running application , C#.NET