Monday, December 1, 2014

Create Windows Task Scheduler C#

Whenever you create a Windows task scheduler basically you concern in two important thing

1.) Create a action that you want to perform.
2.) create the trigger of time interval and occureance to get that action execute.


In order to create a Windows task scheduler through code we shall follow the same pattern.
1.) Connect to Task Service.
2.) Create New task and setup the setting for that task.
3.) Create Trigger
4.) Create Action
5.) Register Task.


Implementation Steps. 

The dll which help us achieve this is C:\Windows\System32\taskschd.dll. When you add this dll as reference it showed up as reference name "TaskScheduler". After adding this reference you just need to follow some steps in order to have that task setup and running. So the simplest task i am going to setup in open Notepad once at specific interval. So step to implement are.

1.) Connect to Task Service
ITaskService taskService = new TaskScheduler.TaskScheduler();
taskService.Connect();

2.) Create New task and setup the setting for that task.
ITaskDefinition taskDefinition = taskService.NewTask(0);
        taskDefinition.Settings.MultipleInstances = _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW;
        taskDefinition.RegistrationInfo.Description = "Testing the creation of a scheduled task via VB .NET";
        taskDefinition.Principal.LogonType = _TASK_LOGON_TYPE.TASK_LOGON_GROUP;
        taskDefinition.Settings.Hidden = false;

3.) Create Trigger
ITimeTrigger taskTrigger = (ITimeTrigger)taskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME);
        taskTrigger.StartBoundary = DateTime.Now.AddMinutes(1).ToString("yyyy-MM-ddTHH:mm:ss" + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).ToString().Substring(0, 6));
        

4.) Create Action
        IExecAction taskAction = (IExecAction)taskDefinition.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
        taskAction.Path = "C:\\windows\\notepad.exe";
        taskAction.Arguments = "";
        taskAction.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

5.) Register Task.
const string taskName = "Simple windows scheduled task";
        ITaskFolder rootFolder = taskService.GetFolder("\\Test");
        rootFolder.RegisterTaskDefinition(taskName, taskDefinition, Convert.ToInt32(_TASK_CREATION.TASK_CREATE_OR_UPDATE), "Administrator", "admin@123", _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD);

SO add the dll and combine the code from step 1 to 5 in single console application and run it you will have one task which run the notpad after 1 minute from now.

I know i am very brief but as a developer i thing a good developer need good direction and he can find the destination itself. and i spend my one full day in order to have configure everything.

Happy Coding!!!!

Tuesday, July 8, 2014

Microsoft Azure Web/WCF Role Consolidation with Relative Publish Folder Path

These days everybody is following SOA architecture so that there application logic can be access from various platforms. So in order to achieve this architecture everybody has minimum one WCF/Web Api service project and one Web Role in their application. Also is order to achieve Microsoft Azure SLA each role should have minimum two instance and should be of medium size. As per July 08,2014 Microsoft Azure Medium instance configuration is as

Name
Virtual Cores
RAM
Price Per Hour
Medium (A2)
2
3.5 GB
$0.16
(~$120/month)

So Medium machine has very good configuration for hosting a single web application. I developed multi-user heavy load application and we always recommend medium instance with variable instances. So if you have small application with 1000 users and two role (WCF and Web). then you need to pay for 4 instances which will be like 120 * 4 = $480/m for only hosting the applications and other data transfer extra. So in these cases we recommend role consolidation having multiple application hosted as website in single role. This is easy task but before that we need to know few thing. 
  • Whenever we host WCF/Web Role in Windows Azure it host the application in IIS. and in IIS we can create multiple application and Virtual Directory. So here we need to do something that we host our Web Role at port 80 (default port) and WCF role at other http port both as separate website. 
Lets do the real stuff. (I never wrote this much theory but it is important to know why we are doing this)
So suppose you have two roles in you application so you just need to Create two separate site nodes in you ServiceDefinition file and also need to create two end points for those sites as follow.

<WebRole name="WebRole1" vmsize="Medium">
<Sites>
      <Site name="Web">
             <Bindings>
                    <Binding name="Endpoint1" endpointName="Endpoint1" />
             </Bindings>
      </Site>
      <Site name="WCFServiceWebRole1" physicalDirectory="..\..\..\PublishDirectory\WCFServiceWebRole1">
              <Bindings>
                     <Binding name="Endpoint2" endpointName="Endpoint2" />
              </Bindings>
      </Site>  
 </Sites>
  <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
      <InputEndpoint name="Endpoint2" protocol="http" port="8080" />
  </Endpoints>
</WebRole>

Now you can see i have created two Sites in Single Web Role and both of them have separate endpoint. I assign Webrole the port 80 so that i am able to open website with direct url like "myurl.cloudapp.net" and wcf at 8080 and it will hosted to myurl.cloudapp.net:8080

Also i want to point out one more thing which will justify this posts Header i.e Relative Publish Folder Path. 
If you see carefully for WCFServiceWebRole1 I have set the phsicalDirectory of that website as relative address. This is the beauty of this post and let me explain how i did that. What i did i just add the some publish script in MSBuild Which as as follows.

<PropertyGroup>
    <PublishPath Condition="'$(PublishPath)' == ''">$(ProjectDir)..\Publish\$(ProjectName)</PublishPath>
    <PublishConfigurationIgnore Condition="'$(PublishConfigurationIgnore)' == ''">Debug</PublishConfigurationIgnore>
  </PropertyGroup>
  <Target Name="PublishToDirectory" AfterTargets="Build" Condition="'$(PublishPath)' != '' AND '$(PublishConfigurationIgnore)' != '' AND '$(Configuration)' != '$(PublishConfigurationIgnore)'">
    <Delete Files="$(PublishPath)\**\*.*" Condition="Exists('$(PublishPath)')" ContinueOnError="true" />
    <!--<Delete Files="$(PublishPath)-Compiled\**\*.*" Condition="Exists('$(PublishPath)-Compiled')" ContinueOnError="true"/>-->
    <MSBuild Projects="$(ProjectPath)" Targets="PipelinePreDeployCopyAllFilesToOneFolder" Properties="Configuration=$(ConfigurationName);_PackageTempDir=$(PublishPath);PackageAsSingleFile=false;DeployOnBuild=True;DeployTarget=Package" />
  </Target>

So what above script will do during build it will publish the WCF Role application to "PublishToDirectory" folder and it also take care of the transformation or the web.config to. NOTE: It will not publish the site in case when Debug Mode is selected. So in Azure configuration i just give the relative address of that Publish folder relative to Project i am working with. So during this approach any developer who is working on this project so everytime when somebody map the TFS then need not to change the project publish folder as per their folder structure everything will taken care automatically.

SO BELOW IS THE IMAGE OF THE MICROSOFT AZURE IIS OF FOUR ROLE THAT WE CONSOLIDATED IN SINGLE ROLE (IN PRODUCTION RIGHT NOW)


ALSO YOU CAN FOUND THE COMPLETE CODE EXAMPLE OF MY ABOVE EXPLANATION AT HERE