SharpDevelop のプロジェクトテンプレートをカスタマイズする

以前、以下の記事を書きましたが、
今回はプロジェクトテンプレートをカスタマイズしてみます。

* [SharpDevelop のファイルテンプレートをカスタマイズする #c# #SharpDevelop - Qiita](http://qiita.com/items/383b8570531cbfb8ed11)

# 今回の目的

新規作成メニューに「コンソールアプリケーション(Log4Net)」を追加する。(最初から以下のロジックを足したもの)

* Log4Netのひな形
* NDesk.Options によるコマンドライン処理のひな形
* 補足されない例外の処理

![](https://lh5.googleusercontent.com/-gLuCupCueHM/UEtM6erMQdI/AAAAAAAAEok/HVGBZ8dORUU/s800/2012-09-07_06h43_00.png)

# 手順

プロジェクトテンプレート等が保存されている場所は以下の場所と仮定します。
環境が異なる場合は読み替えてください。
(`C:\Program Files\SharpDevelop\4.2\data\templates`)

![](https://lh4.googleusercontent.com/-b-ToMuEin3I/UEtNTuueI6I/AAAAAAAAEo4/1v4LqNczXFI/s800/2012-09-08_22h49_12.png)

1. 「 コンソールアプリケーション」のテンプレートの実体は`ConsoleProject.xpt`なので、このファイルをコピーしてリネームします。 -> `ConsoleProjectRohinomiya.xpt`
2. その中身を見ながら、なんとなくこんな感じだろう、と書き換えてみます。
3. SharpDevelop を再起動すれば、新規作成のメニューに出てくるようになります。

すべてのファイルは、以下の場所においておりますので、SharpDevelop の対応するディレクトリに配置してください。

* [SharpDevelop/templates/project/CSharp at master · rohinomiya/SharpDevelop · GitHub](https://github.com/rohinomiya/SharpDevelop/tree/master/templates/project/CSharp)

![](https://lh6.googleusercontent.com/-cPOrAyd7gKw/UEtTbxhHJ1I/AAAAAAAAEps/JgEIykwXq1w/s800/2012-09-08_23h16_09.png)

# テンプレートファイルの中身

```xml:ConsoleProjectRohinomiya.xpt
<?xml version="1.0"?>
<Template originator = "Rohinomiya"
          created      = "2012/09/07"
          lastModified = "2012/09/07">
	
	<!-- Template Header -->
	<TemplateConfiguration>
		<Name>${res:Templates.Project.ConsoleProject.Name}(with log4net)</Name>
		<Category>C#</Category>
		<Subcategory>${res:Templates.File.Categories.WindowsApplications}</Subcategory>
		<Icon>C#.Project.DOSProject</Icon>
		<Description>${res:Templates.Project.ConsoleProject.Description} (with log4net)</Description>
		<SupportedTargetFrameworks>v2.0;v3.5Client</SupportedTargetFrameworks>
	</TemplateConfiguration>
	
	<!-- Actions -->
	<Actions>
		<Open filename = "Program.cs"/>
	</Actions>
	
	<!-- Template Content -->
	<Project language = "C#">
		<ProjectItems>
			<Reference Include="System" />
			<Reference Include="System.Core" />
			<Reference Include="System.Windows.Forms" />
			<Reference Include="log4net">
				<HintPath>C:\Program Files\SharpDevelop\4.2\data\templates\project\CSharp\log4net.dll</HintPath>
                <SpecificVersion>False</SpecificVersion>
				<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
                <Private>True</Private>
            </Reference>
			<Reference Include="NDesk.Options">
				<HintPath>C:\Program Files\SharpDevelop\4.2\data\templates\project\CSharp\NDesk.Options.dll</HintPath>
                <SpecificVersion>False</SpecificVersion>
				<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
                <Private>True</Private>
            </Reference>
		</ProjectItems>
		
		<PropertyGroup>
			<OutputType>Exe</OutputType>
			<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
			<TargetFrameworkProfile></TargetFrameworkProfile>
			<AppDesignerFolder>Properties</AppDesignerFolder>
		</PropertyGroup>
		<Files>
			<File name="Program.cs"><![CDATA[${StandardHeader.C#}
using log4net;
using NDesk.Options;
using Rohinomiya;	// my namespace
using System;
using System.Collections.Generic;

namespace ${StandardNamespace}
{
	class Program
	{
		public static void Main(string[] args)
		{
			HandlerForUnhandledException.GetInstance().HandleUnhandledException();
					
			// TODO: edit output directory in Log4Net.Config.xml
			//ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
			ILog logger = NullLogger.GetInstance();
			
			// TODO: refactor Configuration class
			bool verbose = false;
			bool recursive = false;
			string output_dir = "";

			List<string> extraCommandLineArgs = new List<string>();

			// define command line options
			var p = new OptionSet()
				.Add ("v|version",    dummy => { ShowHelp(); Environment.Exit(0); } )
				.Add ("?|h|help",     dummy => { ShowHelp(); Environment.Exit(0); } )
				.Add ("verbose",          v => { if(v!=null) verbose = true; }      )
				.Add ("o=|output_dir=", dir => { if(dir!=null) output_dir = dir; }  )
				.Add ("r|recursive",      r => { if(r!=null) recursive = true; }    )
				;

			try {
				// extraCommandLineArgs = commandLineArgs except options
				extraCommandLineArgs = p.Parse(Environment.GetCommandLineArgs());
			}
			catch(Exception ex){
				Console.WriteLine(ex.Message);
				Environment.Exit(0);
			}
			
			// todo: parse result 
			Console.WriteLine(String.Format("verbose={0}",verbose.ToString()));
			Console.WriteLine(String.Format("recursive={0}",recursive.ToString()));
			Console.WriteLine(String.Format("output_dir={0}",output_dir));
			
			int index = 0;
			foreach (var arg in extraCommandLineArgs) {
				Console.WriteLine(String.Format("arg[{0}]={1}",index,arg));
				index++;
			}
			
			// TODO: Implement Functionality Here
			
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}

		/// <summary>
		/// Show Help
		/// </summary>
		public static void ShowHelp()
		{
			Console.WriteLine("This is help message.");
		}
	}
}]]></File>
			<File name="Properties\AssemblyInfo.cs" src="DefaultAssemblyInfoLog4Net.cs"/>
			<File name="ClassNullLogger.cs" src="ClassNullLogger.cs"/>
			<File name="Log4net.Config.xml" src="Log4net.Config.xml"/>
			<File name="ClassHandlerForUnhandledException.cs" src="ClassHandlerForUnhandledException.cs"/>
		</Files>		
	</Project>
</Template>
```

# ポイント

ビルド時にDLLをターゲットディレクトリにコピーする。

```xml 
<Reference Include="log4net">
	<HintPath>C:\Program Files\SharpDevelop\4.2\data\templates\project\CSharp\log4net.dll</HintPath>
    <SpecificVersion>False</SpecificVersion>
	<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <Private>True</Private>
</Reference>
```

.NET Framework 4.0 を使用する (.NET Framework 4.0 Client Profile に非ず)

```xml 
<PropertyGroup>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile></TargetFrameworkProfile>
</PropertyGroup>
```
# 参考

* [How to define the target platform inside a .XPT file - SharpDevelop Community](http://community.sharpdevelop.net/forums/p/10951/30160.aspx)

* [SharpDevelop/README.txt at master · icsharpcode/SharpDevelop · GitHub](https://github.com/icsharpcode/SharpDevelop/blob/master/README.txt)