NANT task <exec program="CMD.EXE" exception:

When you use NANT to execute a bat file, use the <arg … /> tag to set parameters and use the workingdir to change the current path location, like:

<exec program="CMD.EXE" commandline="/C DatabaseInstallation.cmd" workingdir="${installPath}">
<arg value="${Database_ServerInstanceName}" />
<arg value="${Database_Name}"/>
<arg value="${Database_Domain}"/>
<arg value="${Database_DtsPackagesFolder}"/>
</exec>

If you use it like:

<exec program="CMD.EXE" commandline="/C ${installPath}\DatabaseInstallation.cmd" workingdir="${installPath}">
<arg value="${Database_ServerInstanceName}" />
<arg value="${Database_Name}"/>
<arg value="${Database_Domain}"/>
<arg value="${Database_DtsPackagesFolder}"/>
</exec>

You will get the exception:

     [exec] ‘C:\Program’ is not recognized as an internal or external command,

     [exec] operable program or batch file.

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

This can occur even if you use quotes:

<exec program="CMD.EXE" commandline="/C &quot;${installPath}\DatabaseInstallation.cmd&quot;" workingdir="${installPath}">
<arg value="${Database_ServerInstanceName}" />
<arg value="${Database_Name}"/>
<arg value="${Database_Domain}"/>
<arg value="${Database_DtsPackagesFolder}"/>
</exec>

Delete IIS6 or IIS7 virtual directory on a website with hostheader, with C# and NANT

using System;
using System.DirectoryServices;
using System.Globalization;
using Ada.Configurator.Common;
using NAnt.Core.Attributes;
using NAnt.Core;
namespace AdaNantTasks
{
/// <summary>
/// Delete an IIS virtual directory on a website with a hostheader.
/// </summary>
[TaskName("deleteVirtualDirectoryTask")]
public class DeleteVirtualDirectoryTask : Task
{
public NantLogger logger = new NantLogger();
public string VirDirSchemaName = "IIsWebVirtualDir";
private string m_server;
[TaskAttribute("server", Required = true)]
[StringValidator(AllowEmpty = false)]
public string Server
{
get { return m_server; }
set { m_server = value; }
}
private string m_virtualDirectoryName;
[TaskAttribute("virtualDirectoryName", Required = true)]
[StringValidator(AllowEmpty = false)]
public string VirtualDirectoryName
{
get { return m_virtualDirectoryName; }
set { m_virtualDirectoryName = value; }
}
private string m_websiteName;
[TaskAttribute("websiteName", Required = true)]
[StringValidator(AllowEmpty = false)]
public string WebsiteName
{
get { return m_websiteName; }
set { m_websiteName = value; }
}
/// <summary>
/// Creates website
/// </summary>
protected override void ExecuteTask()
{
try
{
this.DeleteVirtualDirectory();
Project.Log(Level.Info, string.Format("Virtualdirectory [{0}] created", m_virtualDirectoryName));
}
catch (Exception ex)
{
logger.Log(this.Project, Level.Error, string.Format("VirtualDirectory [{0}] not created, because an exception occurred [{1}]", m_virtualDirectoryName, ex.ToString()));
throw new BuildException("Unable to create website", ex);
}
}
/// <summary>
/// Delete an IIS virtualdirectory
/// </summary>
public void DeleteVirtualDirectory()
{
if (string.IsNullOrEmpty(m_server)) { throw new Exception("Property [Server] can't be null or empty"); } else { Console.WriteLine(string.Format("DeleteVirtualDirectory: [{0}]", m_server)); }
if (string.IsNullOrEmpty(m_virtualDirectoryName)) { throw new Exception("Property [VirtualDirectoryName] can't be null or empty"); } else { Console.WriteLine(string.Format("DeleteVirtualDirectory: [{0}]", m_virtualDirectoryName)); }
if (string.IsNullOrEmpty(m_websiteName)) { throw new Exception("Property [WebsiteName] can't be null or empty"); } else { Console.WriteLine(string.Format("DeleteVirtualDirectory: [{0}]", m_websiteName)); }
int websiteId = this.GetWebSiteId(m_server, m_websiteName);
string iisPath = string.Format("IIS://{0}/w3svc/{1}", m_server, websiteId);
using (DirectoryEntry w3svc = new DirectoryEntry(iisPath))
{
w3svc.RefreshCache();
using (DirectoryEntry folderRoot = w3svc.Children.Find("Root", VirDirSchemaName))
{
folderRoot.RefreshCache();
DirectoryEntry virtualDirectory = null;
try
{
folderRoot.Children.Find(m_virtualDirectoryName, VirDirSchemaName);
folderRoot.Invoke("AppDelete");
folderRoot.Children.Remove(virtualDirectory);
}
catch
{
Console.WriteLine("Virtual directory [{0}] already exists or error during delete", m_virtualDirectoryName);
}
}
}
}
/// <summary>
/// Get website id on websitename
/// </summary>
/// <param name="serverName">Name of the IIS server e.g. localhost</param>
/// <param name="websiteName">Name of the website e.g. test</param>
/// <returns>
/// Less the 0, site does not exist
/// Id of the existing site
/// </returns>
public int GetWebSiteId(string serverName, string websiteName)
{
if (string.IsNullOrEmpty(serverName)) { throw new Exception("Parameter [serverName] can't be null or empty"); } else { Console.WriteLine(string.Format("GetWebSiteId: [{0}]", serverName)); }
if (string.IsNullOrEmpty(websiteName)) { throw new Exception("Parameter [websiteName] can't be null or empty"); } else { Console.WriteLine(string.Format("GetWebSiteId: [{0}]", websiteName)); }
int result = -1;
using (DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", serverName)))
{
w3svc.RefreshCache();
foreach (DirectoryEntry site in w3svc.Children)
{
using (site)
{
site.RefreshCache();
if (site.Properties["ServerComment"] != null)
{
if (site.Properties["ServerComment"].Value != null)
{
if (site.Properties["ServerComment"].Value.ToString().Equals(websiteName, StringComparison.OrdinalIgnoreCase))
{
result = int.Parse(site.Name);
}
}
}
}
}
}
Console.WriteLine(string.Format("GetWebSiteId: [{0}]", result));
return result;
}
}
}

Create IIS6 or IIS7 virtual directory on a website with hostheader, with C# and NANT

using System;
using System.DirectoryServices;
using System.Globalization;
using Ada.Configurator.Common;
using NAnt.Core.Attributes;
using NAnt.Core;
namespace AdaNantTasks
{
[TaskName("createWebSite")]
public class CreateWebsiteTask : Task
{
public NantLogger logger = new NantLogger();
private string m_server;
[TaskAttribute("server", Required = true)]
[StringValidator(AllowEmpty = false)]
public string Server
{
get { return m_server; }
set { m_server = value; }
}
private string m_websiteName;
[TaskAttribute("websiteName", Required = true)]
[StringValidator(AllowEmpty = false)]
public string WebsiteName
{
get { return m_websiteName; }
set { m_websiteName = value; }
}
private string m_binding;
[TaskAttribute("binding", Required = true)]
[StringValidator(AllowEmpty = false)]
public string Binding
{
get { return m_binding; }
set { m_binding = value; }
}
private string m_webFolder;
[TaskAttribute("webFolder", Required = true)]
[StringValidator(AllowEmpty = false)]
public string WebFolder
{
get { return m_webFolder; }
set { m_webFolder = value; }
}
private string m_appPool;
[TaskAttribute("appPool", Required = true)]
[StringValidator(AllowEmpty = false)]
public string AppPool
{
get { return m_appPool; }
set { m_appPool = value; }
}
/// <summary>
/// Creates website
/// </summary>
protected override void ExecuteTask()
{
try
{
int result = CreateWebsite();
switch (result)
{
case 0:
Project.Log(Level.Info, string.Format("Website [{0}] not created, because it already exists", m_websiteName));
break;
default:
Project.Log(Level.Info, string.Format("Website [{0}] created", m_websiteName));
break;
}
}
catch (Exception ex)
{
logger.Log(this.Project, Level.Error, string.Format("Website [{0}] not created, because an exception occurred [{1}]", m_websiteName, ex.ToString()));
throw new BuildException("Unable to create website", ex);
}
}
/// <summary>
/// Create an IIS website.
/// </summary>
/// <returns>Website id</returns>
public int CreateWebsite()
{
if (string.IsNullOrEmpty(m_appPool)) { throw new Exception("Property [AppPool] can't be null or empty"); }
if (string.IsNullOrEmpty(m_binding)) { throw new Exception("Parameter [Binding] can't be null or empty"); }
if (string.IsNullOrEmpty(m_server)) { throw new Exception("Parameter [Server] can't be null or empty"); }
if (string.IsNullOrEmpty(m_webFolder)) { throw new Exception("Parameter [WebFolder] can't be null or empty"); }
if (string.IsNullOrEmpty(m_websiteName)) { throw new Exception("Parameter [WebsiteName] can't be null or empty"); }
int websiteId = 1;
using (DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", m_server)))
{
w3svc.RefreshCache();
websiteId = this.GetWebSiteId(m_server, m_websiteName);
if (websiteId < 0)
{
//Create a website object array
object[] newsite = new object[] { m_websiteName, new object[] { m_binding }, m_webFolder };
//invoke IIsWebService.CreateNewSite
websiteId = (int)w3svc.Invoke("CreateNewSite", newsite);
// get newly created object
using (DirectoryEntry website = new DirectoryEntry(string.Format("IIS://{0}/w3svc/{1}", m_server, websiteId)))
{
website.RefreshCache();
// upgrade Scriptmap to 2.0.50272 (ASP.NET version)
for (int prop = 0; prop < website.Properties["ScriptMaps"].Count; prop++)
{
website.Properties["ScriptMaps"][prop] = website.Properties["ScriptMaps"][prop].ToString().Replace("v1.1.4322", "v2.0.50727");
}
// set application pool
website.Properties["AppPoolId"][0] = m_appPool;
// set Execute Permissions (0 - Scripts only, 512 - Script Only, 516 Script and Execute
website.Properties["AccessFlags"][0] = 512;
// set ReadAccess
website.Properties["AccessRead"][0] = true;
//// set Application Name (friendly name)
//// doesn't seem to work...
//w3svc.Properties["AppFriendlyName"][0] = siteDescription;
// Set Directory Security (Integrated Windows Authentication) 1 = AuthAnonymous, 2 = AuthBasic, 4 =AuthNTLM, 16 = AuthMD5(Digest), 64 = AuthPassport
website.Properties["AuthFlags"][0] = 5;
// save properties to IIS-metabase
website.CommitChanges();
// start website
website.Invoke("Start", null);
}
}
else
{
websiteId = 0;
}
}
return websiteId;
}
/// <summary>
/// Get website id on websitename
/// </summary>
/// <param name="serverName">Name of the IIS server e.g. localhost</param>
/// <param name="websiteName">Name of the website e.g. test</param>
/// <returns>
/// Less the 0, site does not exist
/// Id of the existing site
/// </returns>
public int GetWebSiteId(string serverName, string websiteName)
{
if (string.IsNullOrEmpty(serverName)) { throw new Exception("Parameter [serverName] can't be null or empty"); }
if (string.IsNullOrEmpty(websiteName)) { throw new Exception("Parameter [websiteName] can't be null or empty"); }
int result = -1;
using (DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", serverName)))
{
w3svc.RefreshCache();
foreach (DirectoryEntry site in w3svc.Children)
{
using (site)
{
site.RefreshCache();
if (site.Properties["ServerComment"] != null)
{
if (site.Properties["ServerComment"].Value != null)
{
if (site.Properties["ServerComment"].Value.ToString().Equals(websiteName, StringComparison.OrdinalIgnoreCase))
{
result = int.Parse(site.Name);
}
}
}
}
}
}
return result;
}
}
}

Dump IIS info with C#

To call the function use:  this.DumpIISInfo(new DirectoryEntry("IIS://localhost/w3svc"));
/// <summary>
/// Dump iis info
/// </summary>
/// <returns>
/// 0 = All IIS information is written to the console
/// 1 = Parameter entry was null
/// </returns>
public int DumpIISInfo(DirectoryEntry entry)
{
if (entry == null) { return 1; }
foreach (DirectoryEntry childEntry in entry.Children)
{
using (childEntry)
{
Console.WriteLine(string.Format("Child name [{0}]", childEntry.Name));
foreach (PropertyValueCollection property in childEntry.Properties)
{
Console.WriteLine(string.Format("[{0}] [{1}] [{2}]", childEntry.Name, property.PropertyName, property.Value));
}
if (childEntry.Children != null)
{
this.DumpIISInfo(childEntry);
}
}
}
return 0;
}

Determine if an IIS website or IIS virtualdirectory exist, that run under a given applicationpool, with C#

To call this function use: DoesAppPoolHaveWebsites(new DirectoryEntry(string.Format("IIS://{0}/w3svc", "localhost")), "appPoolName")
 
        /// <summary>
/// Determine if a IIS website running under an applicationpool exists.
/// </summary>
/// <returns></returns>
public bool DoesAppPoolHaveWebsites(DirectoryEntry iisEntry, string appPoolName)
{
bool result = false;
if (iisEntry == null) { throw new Exception("Parameter [iisEntry] can't be null or empty"); }
if (string.IsNullOrEmpty(appPoolName)) { throw new Exception("Parameter [appPoolName] can't be null or empty"); }
foreach (DirectoryEntry child in iisEntry.Children)
{
foreach (PropertyValueCollection property in child.Properties)
{
if (property.PropertyName.Equals("AppPoolId", StringComparison.OrdinalIgnoreCase))
{
if (property.Value != null)
{
if (property.Value.ToString().Equals(appPoolName, StringComparison.OrdinalIgnoreCase))
{
result = true;
break;
}
}
}
}
if (result)
{
break;
}
else
{
if (child.Children != null)
{
if (this.DoesAppPoolHaveWebsites(child, appPoolName))
{
result = true;
}
}
}
}
return result;
}

How to list all IIS applicationpools and properties, with C#

        /// <summary>
/// List all properties of an IIS applicationpool
/// </summary>
/// <param name="serverName">Name of the IIS server e.g. localhost</param>
/// <param name="appPoolName">Name of the applicationpool e.g. test</param>
public void ListAppPoolProperties(string serverName, string appPoolName)
{
if (string.IsNullOrEmpty(serverName)) { throw new Exception("Parameter [serverName] can't be null or empty"); }
if (string.IsNullOrEmpty(appPoolName)) { throw new Exception("Parameter [appPoolName] can't be null or empty"); }
DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc/apppools", serverName));
foreach (DirectoryEntry site in w3svc.Children)
{
Console.WriteLine("Applicationpool");
foreach (PropertyValueCollection property in site.Properties)
{
Console.WriteLine("Applicationpool Property");
Console.WriteLine(string.Format("{0}[{1}]", property.PropertyName, property.Value));
}
if (site.Properties["ServerComment"] != null)
{
if (site.Properties["ServerComment"].Value != null)
{
if (string.Compare(site.Properties["ServerComment"].Value.ToString(), appPoolName, false) == 0)
{
foreach (DirectoryEntry child in site.Children)
{
Console.WriteLine("Applicationpool child");
foreach (PropertyValueCollection property in child.Properties)
{
Console.WriteLine("Applicationpool child property");
Console.WriteLine(string.Format("{0}[{1}]", property.PropertyName, property.Value));
}
}
}
}
}
}
}

How to determine if an IIS website contains virtualdirectories, with C#

       /// <summary>
/// Does the given IIS website contain virtualdirectories.
/// </summary>
/// <returns></returns>
public bool DoesWebsiteContainVirtualDirectories(string website)
{
if (string.IsNullOrEmpty(website)) { throw new Exception("Parameter [website] can't be null or empty"); }
bool result = false;
DirectoryEntry w3svc = new DirectoryEntry("IIS://localhost/w3svc");
foreach (DirectoryEntry site in w3svc.Children)
{
if (site.Properties["ServerComment"] != null)
{
if (site.Properties["ServerComment"].Value != null)
{
if (site.SchemaClassName.Equals("IIsWebServer") && site.Properties["ServerComment"].Value.ToString().Equals(website))
{
foreach (DirectoryEntry child in site.Children)
{
if (!result)
{
foreach (PropertyValueCollection property in child.Properties)
{
if (property.Value != null)
{
if (property.PropertyName.Equals("KeyType") && property.Value.ToString().Equals("IIsWebVirtualDir"))
{
return true;
}
}
}
}
}
}
}
}
}
return result;
}

NANT: Build Microsoft VisualStudio solutions and configure environments

I use NANT to build Microsoft VisualStudio solutions and after deploying software with msi packages, I use NANT to configure the environment (Creating WebSite, Virtual Directories, Custom Eventlogs, register services, create folders, create shares etc)

More information on NANT can be found, here: http://nantcontrib.sourceforge.net/, including documentation for task, types and functions.

I use Edirot4NANT as an GUI tool to run NANT tasks:

 http://www.download.com/Editor4NAnt/3000-2352_4-10531916.html