オブジェクト指向でコードを書く作業

オブジェクト指向プログラミングのメリットといえば・・・

・作業効率の最適化
・生産性の向上
・バグを減らす
・コードの再利用
・コードの管理をしやすくする

といったところか。

現場で開発をやっていて日頃感じるのは、どちらかといったら、オブジェクト思考プログラミングは、コードの管理(可視性・見通し)を高めるための道具に過ぎないように思える。この管理というのがミソでコードだけではなくプロジェクトの管理や人員の管理などの一連の管理を行いやすくするための思考であるというように思えている。

一時期はオブジェクト思考万歳!みたいな風潮があったけど、定着してきているのか、それともオブジェクト指向の限界が見えてきたのか、最近は良かれというような風には余り言われていないように思える。

とはいえ、従来の手続き型?のプログラミングではバグがわんさか生成されることがあり、そのデバッグではかなり苦労する。また、他人が作ったこのようなコードでは、本人しかわからないようなコーディングとなっていることがよくあり、再利用といった観点からはほど遠い。

なので「どっちもどっち」なんですよ。いろんなプロジェクトを仕上げることが多いので、使い分けが必要になってくる。

ただ、開発をやっていて思うのは、オブジェクト思考でプロジェクトを進めると、事務的作業が膨大になった。その反面でコーディングの時間がかなり短縮されたように感じる。テストや評価も比較的やりやすいし、従来のとにかく使ってみてバグがあったら直し、また使ってみて直す、みたいな突貫工事的なことは少なくなる。ま、会社の規模が大きくなるほど、またプロジェクトの規模が大きくなるほど、オブジェクト指向方式は必須になるということ。

視覚障害者がオブジェクト指向プログラミングを行うには、実際のところはコードを書く作業よりも、その事務的な作業で大変なことがある。オブジェクト指向は可視性を高めるという概念があるので、概念そのものを取り入れた開発プロジェクトでは、このようなビジュアルな書類を作成するのが困難かもしれない。支援技術を使いこなせる人や、XMLで直接モデル図を記述できるレベルの視覚障害者であれば、まあどうにでもなるのかもしれないけど、普通のプログラマーだったらちょっと苦労してしまうだろう。

・オブジェクト指向の現実
www.aerith.net/design/demerit-merit-j.html

Windows Installer による MSI パッケージの多言語化

Windows Installer による MSI パッケージの多言語化

<参考にしたサイト>
・ぷりんすの開発メモ 単一msiで多言語に対応したインストーラを作成してみる
prins-note.blogspot.com/2010/02/msi.html
・How To Localize the Setup GUI and Deliver Localized Files Using a MST
www.contactez.net/support/MSITransformLocalization.html
・Orca(msiファイルの編集ツール)をインストールする方法
pasofaq.jp/development/visualbasic/orca.htm

上記のサイト群を何回か読み直してテストコーディングをするとわかってくるのだけど、ちょっと不親切なので、自分のためのメモとしてここでまとめておきます。

Windows Installer では多言語に対応したインストーラが作成できない。
多言語対応とは日本語OSで動いているときには日本語でメッセージを表示し、英語OSであれば英語でメッセージを表示するといった具合。
InstallSield(インストールシールド)では多言語対応インストーラの作成が容易にできるらしいのだけれど、自分の手元にないので、MSIパッケージとして配布可能なWindows Installerでチャレンジ!

1.Microsoft Platform SDK / ORCA の入手
pasofaq.jp/development/visualbasic/orca.htm で説明されている通りに行う。さほど苦労っしない。

2.作業用フォルダの作成
どこでもよいので作業用フォルダを作成する。
たとえば C:temp など。

3.MSIパッケージの準備
MSIパッケージを予めVisual Studioで作成しておく。
このとき Localization プロパティを変更して、対応したい言語をそれぞれ準備する。
たとえば、英語と日本語に対応したければ Localization で English でビルド Japanese でビルドをそれぞれ行い、各パッケージを適当なフォルダ(C:temp)にコピーしておく。

4.スクリプトの準備
以下のVBSを用意する。1で説明した「1.Microsoft Platform SDK / ORCA」がインストールされていること。

C:Program FilesMicrosoft Platform SDKSamplesSysMgmtMsiScripts
WiGenXfm.vbs
WiSubStg.vbs
WiLangId.vbs

自分で作成
ADDSUMINFO4MST.vbs
このファイルは
・How To Localize the Setup GUI and Deliver Localized Files Using a MST
www.contactez.net/support/MSITransformLocalization.html
で照会されていた物。そのまま転用する。

‘Sum.vbs. Argument(0) is the original database. Argument(1) is the
‘ customized database. Argument(2) is the transform file.
Option Explicit

‘ Check arguments
If WScript.Arguments.Count < 2 Then WScript.Echo "Usage is sum.vbs [original database] [customized database] [transform]" WScript.Quit(1) End If ' Connect to Windows Installer object On Error Resume Next Dim installer : Set installer = Nothing Set installer = Wscript.CreateObject("WindowsInstaller.Installer") ' Open databases and transform Dim database1 : Set database1 = installer.OpenDatabase(Wscript.Arguments(0), 0) Dim database2 : Set database2 = installer.OpenDatabase(Wscript.Arguments(1), 0) Dim transform : transform = Wscript.Arguments(2) ' Create and add Summary Information Dim transinfo : transinfo = Database2.CreateTransformSummaryInfo(Database1, transform,0,0) 5.スクリプトの実行 「ファイル名を指定して実行」よいので cmd する。 コマンドプロンプト上で 下記の一連のコマンドを実行。 WiGenXfm.vbs setup.msi setupJpn.msi 1041.mst ADDSUMINFO4MST.vbs "setup.msi" "setupJpn.msi" 1041.mst WiSubStg.vbs setup.msi 1041.mst 1041 WiLangId.vbs setup.msi Package 1033,1041 少し説明。 WiGenXfm.vbs setup.msi setupJpn.msi 1041.mst これは言葉で説明すると、英語用のsetup.msiを使って、日本語用のsetupJpn.msiに対して、異なる部分を1041.mstとして作成するというコマンドになる。そもそもmstはパッケージの差分として使用することが多いそうなのだけれど、このトランスポートを使用して多言語にも対応しようという形式らしい。なお setup.msi と setupJpn.msi はセットアップのビルドで作成したビルドのファイル名である。 ADDSUMINFO4MST.vbs "setup.msi" "setupJpn.msi" 1041.mst これは、setup.msiに1041.mstのカスタム情報を、たぶん埋め込むことかと。 WiSubStg.vbs setup.msi 1041.mst 1041 WiLangId.vbs setup.msi Package 1033,1041 msiのデータテーブルに言語コードを埋め込みパッケージ化。 6.動作確認 ・手動による方法 msiexec.exe /i setup.msi TRANSFORMS=1041.mst (日本語インストーラテスト) ・自動 地域と言語の設定を英語などにして動作確認。 ちょっと駆け足でしたが・・・。 これを読むような人は たぶん professional だと思うので。

C# VB などのアプリにルートCAのデジタル署名を付ける signtoolによる署名

デジタル署名のためのメモ

VB.NET C# ほか

Verisignなどのルート証明機関からのデジタル署名を行う場合に関して、
Visual StudioにおけるNETアプリケーションによるIDE(統合環境)の開発では、
ClickOnceで発行する場合は、ソリューションエクスプローラで右クリックでプロパティを表示し、
署名タブで必要な手続きを行う。方法に関してはCFのとおり。

CF.
・ClickOnce マニフェストの署名
msdn.microsoft.com/ja-jp/library/zfz60ccf(v=VS.90).aspx
・方法 アプリケーション マニフェストおよび配置マニフェストに署名する
msdn.microsoft.com/ja-jp/library/che5h906(v=VS.90).aspx

しかしClickOnceを使用しないでWindows InstallarでMSI形式でセットアップパッケージを配布したい場合には、上述は無理。この場合は自分でビルド後のイベントを追加する必要がある。コマンドラインからsigntoolを使うことになる。

CF.
・方法 Signtool_exe をビルド後のイベントとして起動する (デバイス)
msdn.microsoft.com/ja-jp/library/ms180786(VS.80).aspx

コマンドラインの内容は下記のようになる。framework環境なので、若干、マクロを駆使しなければならない。

“$(FrameworkSDKDir)binsigntool” sign /f “” /p “” /t “http://timestamp.verisign.com/scripts/timestamp.dll” “$(TargetPath)”

ついでにコマンドラインオプションを説明すると、
-f ルートCAからのPFX
-p パスワード
-t タイムスタンプをつける場合タイムスタンプサーバーURLを記述

こんな感じ。

C# 別スレッドからのFormコントロール操作

下記のサイトで掲載されていたVB.NET用のコードをc#で書き換えてみたいと思います。ちょっとわからなかったので調べつつ、しかもちょっと手直ししていますけど。ミソはBeginInvokeでの引数の取り扱いの違いとdelegateによってイベント用のハンドラを実装しているところですかね。

【C#】別スレッドからのFormコントロール操作 ? Insider_NET ? @IT
www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=25804&forum=7

// c# code
public class TestClass {

// 同期用オブジェクト
private System.ComponentModel.ISynchronizeInvoke _SynchronizingObject;

public System.ComponentModel.ISynchronizeInvoke SynchronizingObject
{
get { return _SynchronizingObject; }
set { _SynchronizingObject = value; }
}

// 完了イベント
public delegate void CompletedEventHandler(object sender, CompletedEventArgs e);
public event CompletedEventHandler Completed;

// 完了イベントを発生させる
protected void OnCompleted(CompletedEventArgs e)
{
// SynchronizingObjectが設定されていて、InvokeRequiredがTrueならInvoke
if ( this.Completed != null ) {
if ( (this.SynchronizingObject != null) &&
this.SynchronizingObject.InvokeRequired)
this.SynchronizingObject.BeginInvoke(Completed, new object[] {this, e});
else
Completed(this, e);
}
}

// ワーカスレッドで実行する処理
Private void HeavyProcess()
{
Threading.Thread.Sleep(3000);
OnCompleted(new CompletedEventArgs(“重い処理は完了しました。”));
}
}
public class CompletedEventArgs : EventArgs {

private String _message;

public string Message
{
get { return _message; }
}

internal CompletedEventArgs(string msg)
{
_message = msg;
System.Media.SystemSounds.Beep.Play();
}

}

Sandcastle が VS2010 で使えるようになった

まだ日本のサイトではどこもアナウンスしていなかったようなので一応お知らせまで。

SandcastleがVS2010(Visual Studio 2010)に暫定対応したようです。
Sandcastle-June 2010 Release (Version 2.6.1062.1)

Sandcastle-June 2010 Release (Version 2.6.1062.1)
sandcastle.codeplex.com/releases/view/47665

またGUIベースでsandcastleドキュメントの生成を行う「Sandcastle Help File Builder」も、この時期ちょくちょくアップグレードされています。
shfb.codeplex.com/releases/view/40105

それぞれ最新のパッチを当てることでVS2010でのXMLスキーマで使えるようになります。

C++/CLIでのXMLを、上記の構成でビルドしてみたところ、適切にCHMまで変換されています。
これでVS2010への開発移行が安心してできそうですね。

仕様書もたくさん書かなければならない昨今プログラマの人たちに朗報です。

C++ CLI アセンブリ署名

C++ CLI アセンブリ署名

とにかくめんどくせえ。メモ。

ルートCA(ex.Verisign& ETC)の署名は signcode で行え!
SNKによる厳密な名前による署名は sn.exe -k で行え!
ってことか。

秘密キーなんて紛らわしい用語を使用するからルートCAに含まれる何かなのかと思って一生懸命調べてしまったYO。
しかもPFXからSNKに無理矢理変換したりとかして、まったく意味ないじゃん。
>Unfortunately, a strong name does not provide a way to identify what entity created the assembly.

C++/CLI周りは、この辺のメンテがまったくされていないどころか、ドキュメントも適当すぎていらいらするよほんと。

googleせんせに訪ねてみて、一番参考になったところは、以下の2サイト。

・ Introduction to Code Access Security in the Microsoft _NET Framework
conferences.embarcadero.com/article/32226

・ お仕事日記 - なんちゃってプログラマーのメモ – 厳密名コンパイル
prometa.seesaa.net/article/108816339.html

Visual Studio 2008 Visual 2010 Office テンプレートが消えた

Visual Studio 2008 Visual 2010 Office テンプレートが消えた

VSTO開発をしている人は少ないのか、ネットで調べても解決策が英語でも見つからなかったので、ちょっと乱暴な方法で、とりあえずできたのでメモ。

Visual 2008(VS2008)ではプロジェクトの新規作成でOfficeソリューションに 2003 と 2008 が表示される。問題の現象としては、このうち2007のテンプレートを選択しようとしたらテンプレートが何も表示されなかったということ。2003では一連のVSTOプロジェクトテンプレートが表示されていた状態。
一方、Visual Studio 2010(VS2010)では2007 と 2010 が選択できるようになっているが VS2010 ではこのリストビューアイテムが動的に生成される設計になっているらしく各アイテムを洗濯してもリストビューそのものへのフォーカスができない状態。
先にVS2010の現象を発見したため、リストビューに対する、VSのキーボードナビゲーションそのものの問題かと思ってMicrosoftアクセシビリティの担当者に尋ねてみたんだけど、それはアクセシビリティではないのでVSTOサポート窓口で訪ねてくれとのこと。
自分で調査するうちに上述のようなリストビューであることがわかり確かにアクセシビリティとは関係ないことがわかったけど、Microsoftの社員ってそんなに狭く深い知識しか知らないのかとちょっと幻滅してしまった。蛇足。
で、いったんVS2008もVS2010もアンインストールして、再インストールを試みるも状況は変わらず。
kame-taro.spaces.live.com/blog/cns!CD806281181610EF!1401.entry の記事を参考に devenv /installvstemplates とかもやったんだけど何も変化なし。
じゃあなんだいということで個人フォルダにVS用の設定情報が書き込まれているはずということで、
C:Documents and Settings[Your account]Application DataMicrosoftVisualStudio
を見つける。別にVSで特別な設定をしているわけでもなかったので、この中に配置されている各バージョンのフォルダをごっそり削除して、再起動をかけてみた。そしたら表示されるようになったわけ。

というわけで、半日インストールやらアンインストールやら、余計な作業をしてしまったけど、こんなに簡単な方法で復活できましたよ、というお話。

余談だけど VS2010ではPIAをアセンブリに含めることができるらしい。まだ実際にVS2010を使ったVSTO作業をしていないのだけれど、コードセキュリティーの苦しみから一つ解放されるのかと思うとかなりうれしい。楽しみ楽しみ。

C++ CLI Managed string UnManaged pointer

This sample string pointer for C# application to c++ CLI DLL.

C# application:
out String value Managed pointer

C++ CLI DLL
String^ % and LPWSTR on unmanaged pointer

// c# Form Application
TestClass obj = new TestClass();
string testBuf = null;
obj.TestFunc(out testBuf);
MessageBox.Show(testBuf);

// c++ CLI Class Library(DLL)
using namespace System::Runtime::InteropServices;

void TestClass::TestFunc(
[Runtime::InteropServices::Out] String^ %buf
)
{
LPWSTR msg ;
LPCWSTR wcs = L”TestFunc Loaded”;
BSTR tmp = ::SysAllocString(wcs);
if ( tmp == NULL ) {
return ;
}

SysFreeString(msg);
msg = tmp;

buf = Marshal::PtrToStringUni((IntPtr)msg);
}

c# Application to C++/CLI ref, out, Keywords

c# Application to C++/CLI ref, out, Keywords

c# Application to C++/CLI ref, out, Keywords

// [ref] keyword
// c# code
void Csharp_TestFunc1()
{
TestObject obj = new TestObject();
int i = 0;
obj.TestFunc1(ref i);
MessageBox.Show(i.ToString());
}

// c++/cli
void cpp_TestFunc1(int %i)
{
i = 1;
}

// [out] keyword
// c# code
void Csharp_TestFunc2()
{
TestObject obj = new TestObject();
int i;
obj.TestFunc2(out i);
MessageBox.Show(i.ToString());
}

// c++/cli
void cpp_TestFunc2([Runtime::InteropServices::Out] int %i)
{
i = 1;
}

javascript + html + ページ読み込み時 + focus

IEなどのjavascriptが有効なウェブブラウザでページ読み込み時の初期フォーカスを設定する方法。
HTML上のbody要素を次のように変更。
<body onLoad=”document.getElementById(‘content’).focus();”>
次にページを読み込んだときに初期フォーカスを設定したいリンク(a href)にbody要素で設定したIDを追加する。
<a href=”hogehoge.html” id=”content”>コンテンツ</a>
以上。