Showing posts with label SDC Tasks. Show all posts
Showing posts with label SDC Tasks. Show all posts

Tuesday, September 2, 2008

Using NAnt custom task to wrap SDC Task to create VDir

I got my VDir code working, but there are some caveats that have to be watched, I've found.



   1:  using System;

   2:  using System.Text;

   3:  using NAnt.Core;

   4:  using NAnt.Core.Attributes;

   5:  using Microsoft.Sdc.Tasks;

   6:  using Microsoft.Build.Utilities;

   7:  using Microsoft.Build.Framework;

   8:  namespace Auswipe.NAntTasks.VDirTasks {

   9:    # region Delete VDir

  10:    [TaskName("deletevdir")]

  11:    public class DeleteVDir : NAnt.Core.Task {

  12:      private string vDirToDelete;

  13:      private string machineName;

  14:      private string webSiteName;

  15:      [TaskAttribute("vdirtodelete", Required = true)]

  16:      [StringValidator(AllowEmpty = false)]

  17:      public string VDirToDelete {

  18:        get { return vDirToDelete; }

  19:        set { vDirToDelete = value; }

  20:      }

  21:      [TaskAttribute("machinename", Required = true)]

  22:      [StringValidator(AllowEmpty = false)]

  23:      public string MachineName {

  24:        get { return machineName; }

  25:        set { machineName = value; }

  26:      }

  27:      [TaskAttribute("websitename", Required = true)]

  28:      [StringValidator(AllowEmpty = false)]

  29:      public string WebSiteName {

  30:        get { return webSiteName; }

  31:        set { webSiteName = value; }

  32:      }

  33:      protected override void ExecuteTask() {

  34:        Project.Log(Level.Info, "Auswipe.NAntTasks.VDirTasks : The following AppPool will be deleted: '" + vDirToDelete + "'");

  35:        try {

  36:          Microsoft.Sdc.Tasks.Web.WebSite.DeleteVirtualDirectory delVDirObject = new Microsoft.Sdc.Tasks.Web.WebSite.DeleteVirtualDirectory();

  37:          delVDirObject.MachineName          = machineName;

  38:          delVDirObject.VirtualDirectoryName = vDirToDelete;

  39:          delVDirObject.WebSiteName          = webSiteName;

  40:          if (delVDirObject.Execute()) {

  41:            Project.Log(Level.Info, "Auswipe.NAntTasks.VDirTasks : The VDir '" + vDirToDelete + "' was successful deleted.");

  42:          } else {

  43:            Project.Log(Level.Error, "Auswipe.NAntTasks.VDirTasks : ERROR: The VDir '" + vDirToDelete + "' was NOT deleted but an exception was not thrown.");

  44:          };

  45:        } catch (Exception e) {

  46:          Project.Log(Level.Error, "Auswipe.NAntTasks.VDirTasks : VDir deletion failed with the resulting exception:");

  47:          Project.Log(Level.Error, e.ToString());

  48:        };

  49:      }

  50:    }

  51:    #endregion

  52:    # region Create VDir

  53:    [TaskName("createvdir")]

  54:    public class CreateVDir : NAnt.Core.Task {

  55:      private string vDirName;

  56:      private string webSiteName;

  57:      private string appPoolName;

  58:      private string machineName;

  59:      private string fullPath;

  60:      [TaskAttribute("apppoolname", Required = true)]

  61:      [StringValidator(AllowEmpty = false)]

  62:      public string AppPoolName {

  63:        get { return appPoolName; }

  64:        set { appPoolName = value; }

  65:      }

  66:      [TaskAttribute("vdirname", Required = true)]

  67:      [StringValidator(AllowEmpty = false)]

  68:      public string VDirName {

  69:        get { return vDirName; }

  70:        set { vDirName = value; }

  71:      }

  72:      [TaskAttribute("website", Required = true)]

  73:      [StringValidator(AllowEmpty = false)]

  74:      public string WebSite {

  75:        get { return webSiteName; }

  76:        set { webSiteName = value; }

  77:      }

  78:      [TaskAttribute("machinename", Required = true)]

  79:      [StringValidator(AllowEmpty = false)]

  80:      public string MachineName {

  81:        get { return machineName; }

  82:        set { machineName = value; }

  83:      }

  84:      [TaskAttribute("path", Required = true)]

  85:      [StringValidator(AllowEmpty = false)]

  86:      public string FullPath {

  87:        get { return fullPath; }

  88:        set { fullPath = value; }

  89:      }

  90:      protected override void ExecuteTask() {

  91:        Project.Log(Level.Info, "Auswipe.NAntTasks.VDirTasks : The following VDir will be created: '" + vDirName + "'");

  92:        try {

  93:          Microsoft.Sdc.Tasks.Web.WebSite.CreateVirtualDirectory createVDirObject = new Microsoft.Sdc.Tasks.Web.WebSite.CreateVirtualDirectory();

  94:          createVDirObject.AppCreate            = true;

  95:          createVDirObject.AppPoolId            = appPoolName;

  96:          createVDirObject.MachineName          = machineName;

  97:          createVDirObject.VirtualDirectoryName = vDirName;

  98:          createVDirObject.WebSiteName          = webSiteName;

  99:          createVDirObject.Path                 = fullPath;

 100:          if (createVDirObject.Execute()) {

 101:            Project.Log(Level.Info, "Auswipe.NAntTasks.VDirTasks : The VDir '" + vDirName + "' was successfuly created.");

 102:          } else {

 103:            Project.Log(Level.Error, "Auswipe.NAntTasks.VDirTasks : ERROR: The VDir '" + vDirName + "' was NOT created but an exception was not thrown.");

 104:          };

 105:        } catch (Exception e) {

 106:          Project.Log(Level.Error, "Auswipe.NAntTasks.VDirTasks : VDir creation failed with the resulting exception:");

 107:          Project.Log(Level.Error, e.ToString());

 108:        };

 109:      }

 110:    }

 111:    #endregion

 112:  }



A caveat that I've found though is that even though the invoked SDC Task might run into a problem during the .Execute call, .Execute still returns a true so my NAnt task doesn't know if the process has ran into a problem.

In the example below, I'm trying to create a VDir with an AppPool that doesn't exist:

8<-------------------------------------------
NAnt 0.85 (Build 0.85.2478.0; release; 10/14/2006)
Copyright (C) 2001-2006 Gerry Shaw
http://nant.sourceforge.net

Buildfile: file:///C:/customtask/default.build
Target framework: Microsoft .NET Framework 2.0
Target(s) specified: test-task

[loadtasks] Scanning assembly "Auswipe.NAntTasks.VDirTasks" for extensions.
[loadtasks] Scanning assembly "Auswipe.NAntTasks.AppPoolTasks" for extensions.

test-task:

[echo] Creating VDir
Auswipe.NAntTasks.VDirTasks : The following VDir will be created: 'someVDir'
Creating virtual directory "someVDir".
A task error has occured.
Message = Exception has been thrown by the target of an invocation.
VirtualDirectoryName = someVDir
Path = c:\somewebsite
MachineName = Auswipel-rfs2we
WebSiteName = Default Web Site
WebAppName =
AppPoolId = AppPoolDoesNotExist
AppCreate = True
AnonymousUserName =
AnonymousUserPassword =
UncUserName =
UncPassword =
AuthFlags =
AccessFlags =

at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
at Microsoft.Sdc.Tasks.Configuration.Web.VirtualDirectory.AppCreate3() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\Configuration\Web\VirtualDirectory.cs:line 324
at Microsoft.Sdc.Tasks.Web.WebSite.CreateVirtualDirectory.InternalExecute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\Web\WebSite\CreateVirtualDirectory.cs:line 315
at Microsoft.Sdc.Tasks.TaskBase.Execute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\TaskBase.cs:line 66
Element not found. (Exception from HRESULT: 0x80070490)

PseudoEngineException
at Microsoft.Sdc.Tasks.PseudoBuildEngine.LogErrorEvent(BuildErrorEventArgs eventArgs) in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\PseudoBuildEngine.cs:line 77
at Microsoft.Build.Utilities.TaskLoggingHelper.LogError(String subcategory, String errorCode, String helpKeyword, String file, Int32 lineNumber, Int32 columnNumber, Int32 endLineNumber, Int32 endColumnNumber, String message, Object[] messageArgs)
at Microsoft.Build.Utilities.TaskLoggingHelper.LogError(String message, Object[] messageArgs)
at Microsoft.Sdc.Tasks.TaskBase.Execute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\TaskBase.cs:line 95
Auswipe.NAntTasks.VDirTasks : VDir creation failed with the resulting exception:
System.ApplicationException: PseudoEngineException
at Microsoft.Sdc.Tasks.PseudoBuildEngine.LogErrorEvent(BuildErrorEventArgs eventArgs) in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\PseudoBuildEngine.cs:line 77
at Microsoft.Build.Utilities.TaskLoggingHelper.LogError(String subcategory, String errorCode, String helpKeyword, String file, Int32 lineNumber, Int32 columnNumber, Int32 endLineNumber, Int32 endColumnNumber, String message, Object[] messageArgs)
at Microsoft.Build.Utilities.TaskLoggingHelper.LogErrorFromException(Exception exception, Boolean showStackTrace, Boolean showDetail, String file)
at Microsoft.Build.Utilities.TaskLoggingHelper.LogErrorFromException(Exception exception, Boolean showStackTrace)
at Microsoft.Sdc.Tasks.TaskBase.Execute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\TaskBase.cs:line 99
at Auswipe.NAntTasks.VDirTasks.CreateVDir.ExecuteTask()

BUILD SUCCEEDED - 2 non-fatal error(s), 0 warning(s)

Total time: 0.2 seconds.
------------------------------------------->8

You would think that .Execute should return a False for the call but it doesn't. Notice the verbage of "2 non-fatal error(s)" so it appears that the SDC Task does not treat the non-existant Applicaiton Pool as a fatal error. Good to know!

Going back and looking at the IIS Manager we see this for the create VDir:



Notice how the Application Pool is set to "<Invalid Application Pool>."

So, the VDir was created, despite the lack of a valid Application Pool. That's something to be aware of when testing out NAnt tasks that wrap SDC Task functionality.

Sunday, August 31, 2008

Hey, whaddya know? It works!

I finished the first part of my task to create a custom NAnt task that utilizes the SDC Tasks that were originally built for MSBuild. What I am interested in is deleting and creating custom AppPools for IIS as well as deleting and creating vdirs bound to custom AppPools and not DefaultAppPool.

I did some quick and dirty coding today and came up with this first pass:



   1:  using System;

   2:  using System.Text;

   3:  using NAnt.Core;

   4:  using NAnt.Core.Attributes;

   5:  using Microsoft.Sdc.Tasks;

   6:  using Microsoft.Build.Utilities;

   7:  using Microsoft.Build.Framework;

   8:  namespace Auswipe.NAntTasks.AppPoolTasks {

   9:    # region DeleteAppPool

  10:    [TaskName("deleteapppool")]

  11:    public class DeleteAppPool : NAnt.Core.Task {

  12:      private string appPoolName;

  13:      private string machineName;

  14:      [TaskAttribute("apppoolname", Required = true)]

  15:      [StringValidator(AllowEmpty = false)]

  16:      public string AppPoolName {

  17:        get { return appPoolName; }

  18:        set { appPoolName = value; }

  19:      }

  20:      [TaskAttribute("machinename", Required = true)]

  21:      [StringValidator(AllowEmpty = false)]

  22:      public string MachineName {

  23:        get { return machineName; }

  24:        set { machineName = value; }

  25:      }

  26:      protected override void ExecuteTask() {

  27:        Project.Log(Level.Info, "Auswipe.NAntTasks.AppPoolTasks : The following AppPool will be deleted: '" + appPoolName + "'");

  28:        try {

  29:          Microsoft.Sdc.Tasks.Web.DeleteAppPool.DeleteAppPool delAppPoolObject = new Microsoft.Sdc.Tasks.Web.DeleteAppPool.DeleteAppPool();

  30:          delAppPoolObject.AppPoolName = appPoolName;

  31:          delAppPoolObject.MachineName = machineName;

  32:          if (delAppPoolObject.Execute()) {

  33:            Project.Log(Level.Info, "Auswipe.NAntTasks.AppPoolTasks : The AppPool '" + appPoolName + "' was successful deleted.");

  34:          } else {

  35:            Project.Log(Level.Error, "Auswipe.NAntTasks.AppPoolTasks : ERROR: The AppPool '" + appPoolName + "' was NOT deleted but an exception was not thrown.");

  36:          };

  37:        } catch (Exception e) {

  38:          Project.Log(Level.Error, "Auswipe.NAntTasks.AppPoolTasks : AppPool deletion failed with the resulting exception:");

  39:          Project.Log(Level.Error, e.ToString());

  40:        };

  41:      }

  42:    }

  43:    #endregion

  44:    # region Create AppPool

  45:    [TaskName("createapppool")]

  46:    public class CreateAppPool : NAnt.Core.Task {

  47:      private string appPoolName;

  48:      private string userName;

  49:      private string passWord;

  50:      private string userDomain;

  51:      private string machineName;

  52:      [TaskAttribute("apppoolname", Required = true)]

  53:      [StringValidator(AllowEmpty = false)]

  54:      public string AppPoolName {

  55:        get { return appPoolName; }

  56:        set { appPoolName = value; }

  57:      }

  58:      [TaskAttribute("username", Required = true)]

  59:      [StringValidator(AllowEmpty = false)]

  60:      public string UserName {

  61:        get { return userName; }

  62:        set { userName = value; }

  63:      }

  64:      [TaskAttribute("password", Required = true)]

  65:      [StringValidator(AllowEmpty = false)]

  66:      public string PassWord {

  67:        get { return passWord; }

  68:        set { passWord = value; }

  69:      }

  70:      [TaskAttribute("machinename", Required = true)]

  71:      [StringValidator(AllowEmpty = false)]

  72:      public string MachineName {

  73:        get { return machineName; }

  74:        set { machineName = value; }

  75:      }

  76:      protected override void ExecuteTask() {

  77:        Project.Log(Level.Info, "Auswipe.NAntTasks.AppPoolTasks : The following AppPool will be created: '" + appPoolName + "'");

  78:        try {

  79:          Microsoft.Sdc.Tasks.Web.AppPool.Create createAppPoolObject = new Microsoft.Sdc.Tasks.Web.AppPool.Create();

  80:          createAppPoolObject.AppPoolName  = appPoolName;

  81:          createAppPoolObject.IdentityType = "SpecifiedUserAccount";

  82:          createAppPoolObject.Identity     = userName;

  83:          createAppPoolObject.Password     = passWord;

  84:          createAppPoolObject.MachineName  = machineName;

  85:          if (createAppPoolObject.Execute()) {

  86:            Project.Log(Level.Info, "Auswipe.NAntTasks.AppPoolTasks : The AppPool '" + appPoolName + "' was successfuly created.");

  87:          } else {

  88:            Project.Log(Level.Error, "Auswipe.NAntTasks.AppPoolTasks : ERROR: The AppPool '" + appPoolName + "' was NOT created but an exception was not thrown.");

  89:          };

  90:        } catch (Exception e) {

  91:          Project.Log(Level.Error, "Auswipe.NAntTasks.AppPoolTasks : AppPool creation failed with the resulting exception:");

  92:          Project.Log(Level.Error, e.ToString());

  93:        };

  94:      }

  95:    }

  96:    #endregion

  97:  }



After I created my Auswipe.NAntTasks.AppPoolTasks.dll I had to copy both Auswipe.NAntTasks.AppPoolTasks.dll and Microsoft.Sdc.Tasks.dll to the subdir where I put my default.build that I've been playing with so that the code could properly execute and create my AppPool.

Here is my default.build script for NAnt:

8<-----------------------------------------


   1:   

   2:  <?xml version="1.0"?>

   3:  <project name="Task Test" default="test-task" basedir="." xmlns="http://nant.sf.net/release/0.86-beta1/nant.xsd">

   4:   

   5:    <loadtasks assembly="Auswipe.NAntTasks.AppPoolTasks.dll" />

   6:   

   7:    <target name="test-task">    

   8:      <echo message="Deleting AppPool."/>

   9:      <deleteapppool apppoolname = "AuswipeAppPool"

  10:                     machinename = "Auswipel-rfs2we"

  11:       />

  12:   

  13:      <echo message="Create AppPool."/>

  14:      <createapppool apppoolname = "AuswipeAppPool"

  15:                     username    = "AuswipeAppPoolUser"

  16:                     password    = "supersekrit"

  17:                     machinename = "Auswipel-rfs2we"

  18:      />

  19:    </target>                                   

  20:      

  21:  </project>


----------------------------------------->8

And here is the output from the execution:

8<-----------------------------------------


   1:  C:\customtask>nant /f:default.build test-task

   2:  NAnt 0.85 (Build 0.85.2478.0; release; 10/14/2006)

   3:  Copyright (C) 2001-2006 Gerry Shaw

   4:  http://nant.sourceforge.net

   5:   

   6:  Buildfile: file:///C:/customtask/default.build

   7:  Target framework: Microsoft .NET Framework 2.0

   8:  Target(s) specified: test-task

   9:   

  10:  [loadtasks] Scanning assembly "Auswipe.NAntTasks.AppPoolTasks" for extensions.

  11:   

  12:  test-task:

  13:   

  14:       [echo] Deleting AppPool.

  15:  Auswipe.NAntTasks.AppPoolTasks : The following AppPool will be deleted: 'AuswipeAppPool'

  16:  Auswipe.NAntTasks.AppPoolTasks : The AppPool 'AuswipeAppPool' was successful deleted.

  17:       [echo] Create AppPool.

  18:  Auswipe.NAntTasks.AppPoolTasks : The following AppPool will be created: 'AuswipeAppPool'

  19:  Creating app pool "AuswipeAppPool".

  20:  Auswipe.NAntTasks.AppPoolTasks : The AppPool 'AuswipeAppPool' was successfuly created.

  21:   

  22:  BUILD SUCCEEDED

  23:   

  24:  Total time: 0.1 seconds.


----------------------------------------->8

Here we see a screen shot of the system before NAnt execution:



Now I execute the NAnt script and re-fresh the IIS manager view of AppPools and lo-and-behold! It worked!



I checked the properties of the newly created AppPool and we see that it has the credentials I specified in the default.build. Hazzah!



Now the next step is to go forth and code the deletion and creation of vdirs with the SDC Tasks.

Nifty!