PowerShellでアイコンを作ることが出来ましたので、アイコンを組み込んだプロジェクトのようなものを作成してみます。
<#
.SYNOPSIS
.csproj新規作成
.EXAMPLE
New-Csproj -ProjectName プロジェクト名 [-Target:winexe|exe] [-Outdir:"."]
#>
Add-Type -AssemblyName System
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Set-StrictMode -Version Latest
$ErrorActionPreference = "STOP"
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Form
function CreateResx
{
param(
[string]
$IconPath,
[string]
$OutPath
)
$fs = [System.IO.FileStream]::new($IconPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
$Icon = [System.Drawing.Icon]::new($fs)
$fs.Close()
$resx = [System.Resources.ResXResourceWriter]::new($OutPath) | % {
$_.AddResource("APP_ICON",$Icon)
$_
}
$resx.Close()
$Icon.Dispose()
}
function CreateTextIcon
{
param(
[string]
$Text,
[string]
$OutPath,
[int]
$W = 64,
[int]
$H = 64
)
$Bitmap = [System.Drawing.Bitmap]::new(64, 64, [System.Drawing.Imaging.PixelFormat]::Format24bppRgb)
$g = [System.Drawing.Graphics]::FromImage($Bitmap)
# 黒で塗りつぶし
$rect = [System.Drawing.Rectangle]::new(0, 0, $W, $H)
$g.FillRectangle([System.Drawing.Brushes]::Black, $rect);
# 文字を描く
$font = [System.Drawing.Font]::new("MS UI Gothic", 32);
$g.DrawString($Text.Substring(0, 2), $font, [System.Drawing.Brushes]::White, 0, 0);
$g.Dispose()
$icon = [System.Drawing.Icon]::FromHandle($Bitmap.GetHicon())
$fs = [System.IO.FileStream]::new($OutPath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
$icon.Save($fs)
$fs.Close()
$icon.Dispose()
$Bitmap.Dispose()
}
function New-Csproj
{
param(
[Parameter(ValueFromPipeline=$false,Mandatory=$true)]
[string]
$ProjectName,
[Parameter(ValueFromPipeline=$false,Mandatory=$false)]
[string]
$Target = "winexe",
[Parameter(ValueFromPipeline=$false,Mandatory=$false)]
[string]
$Outdir = (Resolve-Path(".")).Path
)
$cspoj_temp = @'
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AssemblyName></AssemblyName>
<OutputPath>Bin\</OutputPath>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs"/>
<Reference Include="System.Windows.Forms.dll" />
<Reference Include="System.Drawing.dll" />
<Reference Include="System.IO.Compression.dll" />
<Reference Include="System.IO.Compression.FileSystem.dll" />
</ItemGroup>
<Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" TargetType="" References="@(Reference)" Resources="@(Resource)" OutputAssembly="$(OutputPath)$(AssemblyName).exe"/>
</Target>
<Target Name="Clean" >
<Delete Files="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<Target Name="Run" DependsOnTargets="Rebuild">
<Exec Command="$(OutputPath)$(AssemblyName).exe" />
</Target>
</Project>
'@
# アプリケーションのソースファイルを作成
$consol_app_temp = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ${projectname}
{
class Program
{
// アプリケーションのエントリポイント
static void Main(string[] args)
{
Console.Write("${projectname}");
}
}
}
"@
$form_app_temp = @"
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;
using System.IO;
using System.IO.Compression;
using System.Resources;
namespace ${projectname}
{
class Form1 : Form
{
public Form1()
{
var asm = this.GetType().Assembly;
using (var s = asm.GetManifestResourceStream("${projectname}.resx"))
using (var r = new ResXResourceSet(s))
{
this.Icon = r.GetObject("APP_ICON") as Icon;
}
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "${projectname}";
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new Form1());
}
}
}
"@
# プロジェクト用ディレクトリの作成
$projdir = Join-Path $Outdir $ProjectName
if (-not(Test-Path($projdir))) {
mkdir $projdir | Out-Null
}
# csprojの作成
$local = Join-Path $projdir ("{0}.csproj" -f $ProjectName)
$xml = [xml]$cspoj_temp
$xml.Project.PropertyGroup.AssemblyName = $projectname
$xml.Project.Target | ? {$_.Name -eq "Build"} | % {
$_.Csc.TargetType = $Target
}
$source_path = Join-Path $projdir ("{0}.cs" -f $projectname)
if ($Target -eq "exe") {
$source = $consol_app_temp
$source | %{[Text.Encoding]::UTF8.GetBytes($_)} | Set-Content $source_path -Encoding Byte
}
if ($Target -eq "winexe") {
$source_path = Join-Path $projdir "From1.cs"
$source = $form_app_temp
$source | %{[Text.Encoding]::UTF8.GetBytes($_)} | Set-Content $source_path -Encoding Byte
# アプリケーションアイコンの作成
$iconPath = Join-Path $projdir "${ProjectName}.ico"
CreateTextIcon $ProjectName $iconPath
# resxの作成
$resxPath = (Join-Path $projdir "${ProjectName}.resx")
CreateResx $iconPath $resxPath
#<Resource Include="*.resx" />
$child = $xml.CreateElement("Resource", $xml.Project.xmlns)
$attr = $xml.CreateAttribute("Include")
$attr.Value = "*.resx"
$child.Attributes.Append($attr)
$xml.Project.ItemGroup.AppendChild($child) | Out-Null
#<Csc Sources="@(Compile)" TargetType="" References="@(Reference)" Resources="@(Resource)" Win32Icon="$(AssemblyName).ico" OutputAssembly="$(OutputPath)$(AssemblyName).exe"/>
$attr = $xml.CreateAttribute("Win32Icon")
$attr.Value = '$(AssemblyName).ico'
$xml.Project.Target | ? {$_.Name -eq "Build"} | % {
$_.Csc.Attributes.Append($attr)
}
}
$xml.Save($local)
}
Export-ModuleMember -Function New-Csproj
PowerShellのモジュールですので、c:/Users/<ユーザー名>/Documents/WindowsPowerShell/Modules/New-Csproj/New-Csproj.psm1というファイル名で保存してください。(途中のディレクトリが無い場合はディレクトリを作成)
使い方
New-CSproj <プロジェクト名>
実行するとプロジェクト名のディレクトリが出来上がりますので、そのディレクトリに移動します。
cd <プロジェクト名>
ビルドコマンドを実行します。
msbuild /t:run
フォームウィンドウ上部のタイトルバーの左側にアイコンが割り当てられています。




コメント