Tips 編 障害編
- (IIS) IIS に ASPX を事後登録する方法
プログラミング編
例として、C# プロジェクトの下に 「【OSK】コンソールアプリケーション」のプロジェクトを追加する方法を紹介します。
以下は、Visual Studio.NET が C:\Program Files\Microsoft Visual Studio .NET 2003 フォルダにインストールされている場合を想定しています。
C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\CSharpProjects フォルダに対して、以下の操作を行ないます。
vsz ファイルを作成します。ここでは OSKCSharpConsole.vsz のファイルを新規作成し、内容を以下のようにします。適当な名前のファイル名にしてください。
VSWIZARD 7.0 Wizard=VsWizard.VsWizardEngine.7.1 Param= WIZARD_NAME = OSKCSharpConsoleWiz" Param="WIZARD_UI = FALSE" Param="PROJECT_TYPE = CSPROJ"
コンソールアプリケーションの変更の場合は、CSharpConsole.vsz をコピーして変更すると効率が良いでしょう。
CSharpConsole.vsz の CSharpConsoleWiz を適当な名前に変更します。ここでは OSKCSharpConsoleWiz にしています。
OSKCSarp.vsdir を新規作成し、内容を以下のようにします。
OSKCSharpConsole.vsz|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|【OSK】コンソールアプリケーション|70|
OSK テンプレートのコンソールアプリケーションを作成します。|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}
|4548| |OSKConsole
CSharp.vsdir の CSharpConsole.vsz 行を参考にして、変更します。
- OSKCSharpConsole.vsz は 1.1 で作成したファイル名になります。{...} の内容はそのままにします。
- 「【OSK】コンソールアプリケーション」は、プロジェクトの名称になります。「OSK テンプレートのコンソールアプリケーションを作成します。」は、プロジェクトの説明になります。
- 70 はアイコンの表示位置、4548 はアイコン番号を表しています。同じコンソールアプリケーションですので、これらはそのままにします。
- 「OSKConsole」はプロジェクト名のデフォルトになります。
C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\VC#Wizards の下の CSharpConsoleWiz をOSKCSharpConsoleWiz として、コピーします。
OSKCSharpConsoleWiz は 1.1 のファイルで指定したファイル名になります。
生成するコードテンプレートを変更したいときは、OSKCSharpConsoleWiz\Templates\1041\file1.cs を変更します。
例えば、Copyright を付け、コメントの説明を省くなどをします。

また、実際のプログラミング作業で定型的に出現するコードやコメントを予め、生成するのもいいでしょう。
ウィザードの中のファイルの変更により、各種の変更が行えます。例えば、ビルドオプション、ファイルのインクルード、参照の設定など、すべての設定変更が行えます。
実際のプロジェクトを作成し、それをプロジェクトに合うようにカスタマイズしたプロジェクトファイルを元に変更を行うのが、便利です。
生成したプロジェクトファイルを今回のウィザードファイルにマージすることによって、各種の変更を行います。
設定ファイルは、XML で記述されていますので、上記をせずとも、比較的容易にカスタマイズすることもできます。
また VS.NET は簡易的な XML エディタ機能もありますので、そのまま編集も便利にできます。
Visual Studio.NET を起動して、[ファイル] [新規作成] [プロジェクト] を操作します。「新しいプロジェクト」ウィンドウが表示されますので、「Visual C# プロジェクト」を選択してみます。
そうすると、新たに「【OSK】コンソールアプリケーション」が追加されているのがわかります。

[OK] ボタンをクリックしますと、コードテンプレートに従ったコードが生成されます。以下にコードを示します。
/* Copyright (C) 2005 Oki Software Co., Ltd. */
using System;
namespace OSKConsole1
{
/// <summary>
/// Class1
/// </summary>
class Class1
{
/// <summary>
///
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
//
//
}
}
}
コンソールアプリケーションのような簡単なプロジェクトでない、複雑で面倒なプロジェクトを作成するときは、2.2 (2) でも書きましたが、通常の Visual Studio.NET のプロジェクトで作業形態に合うプロジェクトを生成し、プログラムを作成します。
その中で必要なファイルを既存のプロジェクトテンプレートに合わせて、変更を行います。
経験から言って、オリジナルのプロジェクトテンプレートを直接変更するのではなく、上記の手順を踏んで、新規に作成する方が安全で、他の作業にも転用でき、結局、効率が良くなるでしょう。
(2005/02/03 gomi521@oki.com)
ngen コマンドによって、事前コンパイルが行えます。(ngen は Native Image Generator の略)。
使い方は ngen [DLL または EXE ファイル名] のように使います。
ngen でヘルプが表示されますので、それを参照してください。 また、コマンドの詳細は ここ にあります。
但し、すべてのプログラムにこれを適用すれば、いいという意味ではありません。起動時のコストと抽象化とのトレードオフを考えて、使うようにした方がいいでしょう。
また、ngen を手で一々実行するということではなくて、例えば、配付のときに機械的に行えるようにしておく方がいいでしょう。
(2005/02/21 gomi521@oki.com)
環境変数を設定することで、コンソールからビルドなどが行えるようになります。また C# も同様に行えます。
ここで、Visual Studio.NET をインストールした場所を C:\Program Files\Microsoft Visual Studio .NET 2003 とします。
- 一時的に行う方法
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.batを実行することによって、必要な環境変数が設定されます。
- 常設的に設定する方法
環境変数 path, include, lib にそれぞれ必要なパスを設定します。
各々の環境に応じて、適宜変更してお使いください。
v1.1.4322 や v1.1 は VisualStudio.NET の版数です。これは上記のvsvars32.bat の先頭に記述されています。
PATH
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322;
INCLUDE
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\ATLMFC\INCLUDE;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\PlatformSDK\include\prerelease;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\PlatformSDK\include;C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\include;
LIB
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\LIB;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\PlatformSDK\lib\prerelease;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\PlatformSDK\lib;C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\lib;
これにより、cl や link がコンソールから使えるようになります。
(2005/10/04 gomi521@oki.com)
IIS が ASP.NET(ASPX)を認識していないことが原因です。
IIS を動作させてから、.NET Framework1.1 をインストールする必要がありました。
ASP.NET の IIS への登録を以下のコマンドで行ないます。
[systemroot]\Microsoft.NET\Framework\[version]\aspnet_regiis.exe -i
[Systemroot] や [version] は各マシンのものに変更してください。
例. Systemroot = windows, version = v1.1.4322
(2005/02/22 gomi521@oki.com)
# この問題に対する直接の回答は、問題点とともに後述します。
ここでは、継承を使った多態性 Polymorphism の機能を使うことでいいかと思います。
つまり、共通の親クラスを用意し、その変数として宣言して使います。
後は Polymorphism により、目的のメソッドが実行されます。
以下に簡単な例を上げます。
Option Strict On Module Module1 Sub Main() Dim aTest As Test ' 親クラスの変数として宣言 aTest = New Test1 ' 子クラスのインスタンスを生成して代入 aTest.Print() ' 子クラス Test1 のメソッドが呼び出される aTest = New Test2 aTest.Print() End Sub End Module Public Class Test Public Overridable Sub Print() Console.WriteLine("Test") End Sub End Class Public Class Test1 Inherits Test Public Overrides Sub Print() Console.WriteLine("Test1") End Sub End Class Public Class Test2 Inherits Test Public Overrides Sub Print() Console.WriteLine("Test2") End Sub End ClassTest はインタフェースでも構いません。というよりもインタフェースである方が明示的です。
問題に対する直接の回答は以下のようになります。
「DirectCast」を使って直接キャスト変換をすれば、Option Strict On のときでも、エラーは出ません。
Option Strict On Module Module1 Sub Main() Dim aObject As Object aObject = New Test DirectCast(aObject, Test).Print() End Sub End Module Public Class Test Public Sub Print() Console.WriteLine("Test") End Sub End Classもちろん、DirectCast は、一般的にはお勧めではありません。決定は実行時まで遅延させるという遅延束縛の利点を損ねています。
(2005/02/22 gomi521@oki.com)
性能
性能という観点で見た場合、どれくらい違うのでしょうか?
性能という面では、特に気にする必要はないかと思います。
遅延束縛でも、継承を用いた多態性 Polymorphism でも、クラスチェックをするということにおいては、同じになります。この意味では同等でしょう。
性能面からは、既にプログラムが存在しているのであれば、Option Strict On と Off を使い分けるのが開発コストが掛からないかと思います。
了解性
Option Strict Off つまり遅延束縛が嫌われる理由は、プログラマが意図しない不用意な型変換が自動的に行われて、それがバグの原因になることです。
一方、継承による多態性は、プログラマが継承を使って制御した中だけで、暗黙的ダウンキャスト(ナローイング)が行われますので、 プログラマが意図しない不用意な自動型変換は行われません。
逆に言えば、遅延束縛は静的な了解性、読解性を損ねています。実行するまで、どのクラスになるかがわからないのですから。つまり、Strict と lazy binding は相反します。P.S.
リフレクションは便利な機能として存在します。例えば、仕様が未定なままプロトタイピングを作るときや、 何100画面、何100機能もあるようなシステムや、動的に画面や機能が追加されるシステムでは、すべてを静的にプログラムするのは、 面倒で、かつバグも出やすいでしょうから、このようなときはリフレクション機能を使うのがいいかと思います。
このリフレクションを使うときに、一部固定な情報があるとします。 例えば、特定のフィールド変数やメソッドが必ず含まれることが分かっているときは、その存在を仮定して、 遅延束縛を使うと簡単にプログラミングできます。
これを継承の多態性を使い、その継承を抽象クラスで作成する方法があります。多重継承をサポートしていない言語では、 大規模なシステムに対しては、複雑怪奇な継承になりがちです。(インタフェースですべてを定義できるときは、VB.NET は多重継承できますので、 この問題はありません。)
このために、リフレクションとともに遅延束縛を使うことがあります。
(2005/02/22 gomi521@oki.com)
例を以下に示します。
Imports System.Reflection Module Module1 Sub Main() Dim type As Type = GetType(Test) ' Test クラスの取得 Dim methods As MethodInfo() = type.GetMethods() ' メソッド群の取得 Dim obj As Object = Activator.CreateInstance(type) ' Test クラスのインスタンスの生成 Dim args(0) As Object ' 引数用配列の生成 For Each mi As MethodInfo In methods Console.Write("Method is {0}. ", mi) Dim result As Object Dim params As ParameterInfo() = mi.GetParameters ' メソッドのパラメータの取得 If params.Length = 0 Then result = mi.Invoke(obj, Nothing) ' 動的なメソッド呼び出し Console.WriteLine(" Result is {0}", result) Next End Sub Public Class Test Public Sub New(ByVal int As Integer) Console.WriteLine("New(int) " + int.ToString) End Sub Public Sub New() Console.WriteLine("New") End Sub Public Overridable Sub Print() Console.WriteLine("Test") End Sub End Class End Moduleクラス Test のすべてのメソッドに対して、引数がないものを選択し、それを呼び出すようにしています。
引数が有るコンストラクタを呼び出して、インスタンスを生成する例を以下に示します。
Dim types(0) As Type ' コンストラクタ検索用 types(0) = GetType(Int32) ' 第一引数が Int32 のコンストラクタを検索するため Dim construction As ConstructorInfo = type.GetConstructor(types) ' コンストラクタの取得 Dim args2(0) As Object args2(0) = 123 Dim obj2 As Object = construction.Invoke(args2) ' インスタンスを生成
Visual Studio.NET はMicrosoft Corporation の登録商標または商標です。