#title(.NETプログラミング研究 創刊号)

#contents

*.NETプログラミング研究 創刊号 [#lb5c9667]

**ご挨拶 [#o43f0007]

はじめまして、こんにちは。「.NETプログラミング研究」発行人の「どぼん!」です。よろしくお願いいたします。

この「.NETプログラミング研究」ではMicrosoft .NET Frameworkに関するプログラミング情報(主にVisual Basic .NETとC#)を紹介することを目的とします。私一人で作成しているメールマガジンのため、たいしたことはできないかもしれませんが、末永くご購読いただければ幸いです。

次にそれぞれの項目について簡単にその趣旨を説明させていただきます。

:.NET Tips|Microsoft .NET Frameworkに関するTipsを紹介します。

:VBユーザーのためのC#|VBユーザーがC#を使う際に役立つ情報を紹介します。

:.NET質問箱|私が管理人をしているサイト「どぼん!のVB道」(http://dobon.net/vb)の掲示板に寄せられた質問とその答えを紹介します。

:ピンポイントリンク|インターネットでは.NETプログラミングに役立つすばらしいTipsやサンプル、ツールなどがたくさん紹介されています。ここでは「○○するにはどうすればいいのか?」といった個々の問題についての解決に役立つページを紹介させていただきます。

**.NET Tips [#w42be267]

***ファイルを関連付けられたソフトで開いて終了まで待機する [#m18f8d53]

#column(注意){{
この記事の最新版は「[[ファイルを関連付けられたソフトで開いて終了まで待機する>http://dobon.net/vb/dotnet/process/openfile.html]]」で公開しています。
}}

ファイルを関連付けられたソフトで開くには次のようにProcessクラスのStartメソッドを使用します。

#code(vbnet){{
System.Diagnostics.Process.Start("C:\test.txt")
}}

さらに終了まで待機するには次のようにProcessクラスのWaitForExitメソッドを使用します。このとき同期的に待機するため待機中はフリーズしたようになります。

#code(vbnet){{
'ファイルを開いて終了まで待機する
Dim objProcess As System.Diagnostics.Process = _
    System.Diagnostics.Process.Start("C:\test.txt")
objProcess.WaitForExit()
'ここを次のようにすると最大10秒間待機だけする
'objProcess.WaitForExit(10000)
MsgBox("終了。")
}}

次の例ではプロセスの終了まで非同期的に待機します。Button1をクリックしてメモ帳を起動し、メモ帳が終了するとOnExitedが呼び出されます。

#code(vbnet){{
Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    'ファイルを開いて終了まで待機する
    Dim objProcess As System.Diagnostics.Process = _
        System.Diagnostics.Process.Start("notepad.exe")
    'プロセスが終了したときに Exited イベントを発生させる
    objProcess.EnableRaisingEvents = True
    'イベントハンドラの追加
    AddHandler objProcess.Exited, AddressOf OnExited
End Sub

Private Sub OnExited(ByVal sender As Object, _
        ByVal e As EventArgs)
    'プロセスが終了したときに実行される
    MsgBox("終了しました。")
End Sub
}}

**VBユーザーのためのC# [#g156e99c]

***VBのSplit関数と同じことをするには? [#uc022581]

#column(注意){{
この記事の最新版は「[[C#でSplit関数の代わりになるものは?>http://dobon.net/vb/dotnet/vb2cs/vbsplit.html]]」で公開しています。
}}

stringクラスのSplitメソッドは区切り文字としてChar型でしか指定できないため、文字列で区切り文字を指定できるVBのSplit関数とは大きく異なります。ではVBのSplit関数のように区切り文字を文字列(string型)で指定できるようにするにはどうすればよいのでしょうか?

これにはMicrosoft.VisualBasic.StringsクラスのSplitメソッドを使う方法とRegexクラス(System.Text.RegularExpression名前空間)のSplitメソッドを使う方法が考えられます。しかしRegexクラスのSplitメソッドはかなり処理速度が遅く、かといってMicrosoft. VisualBasic.Stringsクラスも使いたくない場合もあります。このような時は分割したい文字列内の区切り文字(列)をいったん適当な1文字(分割したい文字列内の分割したくない位置に絶対現れることのない文字)に置換した後、stringクラスのSplitメソッドにより分割した方が速い場合も多いようです。

次のサンプルではRegex.Split、VisualBasic.Strings.Split、string.Splitそれぞれのメソッドを使ってstring型データを改行文字列("\r\n")で分割したときにかかった時間を計っています。この結果ではVisualBasic.Strings.Splitが圧倒的に遅く、string.Splitは文字列を適当に置換してから分割しているにもかかわらずRegex.Splitよりも倍以上速く処理できました。

#code(csharp){{
//いろいろな方法でstring型データを改行文字列("\r\n")で分割し
//その時間を計る
//テキストファイルをstrTextに読み込む
string strFileName = "REDIST.TXT";
System.IO.FileStream fs = new System.IO.FileStream(strFileName,
    System.IO.FileMode.Open);
System.IO.StreamReader sr = new System.IO.StreamReader(fs, 
	System.Text.Encoding.GetEncoding(932));
string strText = sr.ReadToEnd();
sr.Close();

int t1, t2, t3;
string [] s1, s2, s3;

//Regex.Splitで分割する
t1 = System.Environment.TickCount;
s1 = System.Text.RegularExpressions.Regex.Split(strText,
    "\r\n");
t1 = System.Environment.TickCount - t1;

//VisualBasic.Strings.Splitで分割する
t2 = System.Environment.TickCount;
s2 = Microsoft.VisualBasic.Strings.Split(strText, "\r\n", -1,
	Microsoft.VisualBasic.CompareMethod.Binary);
t2 = System.Environment.TickCount - t2;

//string.Splitで分割する
t3 = System.Environment.TickCount;
s3 = strText.Replace("\r\n", "\n").Split('\n');;
t3 = System.Environment.TickCount - t3;

//結果を表示
Console.WriteLine("Regex.Split: {0}", t1);
Console.WriteLine("VisualBasic.Strings.Split: {0}", t2);
Console.WriteLine("string.Split: {0}", t3);
Console.WriteLine("Lines Count: {0}", s3.Length);

//結果の例
//Regex.Split: 521
//VisualBasic.Strings.Split: 1452
//string.Split: 181
}}

**.NET質問箱 [#b398277d]

***Q:表示中の画像ファイルが削除できません! [#xe51b9f8]

#column(注意){{
この記事の最新版は「[[表示中の画像ファイルが削除できない問題の解決法>http://dobon.net/vb/dotnet/graphics/drawpicture2.html]]」で公開しています。
}}

A:「[[画像ファイルを表示>http://dobon.net/vb/dotnet/graphics/drawimage.html]]」で紹介したFromFileメッソドを使用して画像を表示した時や、PictureBox コントロールのImageプロパティをデザイン時に手動でファイルに設定した時は、その画像ファイルがロックされてしまい、削除する事が出来なくなります(「画像ファイルを表示」の例では"C:\Blue hills.jpg"が削除できません)。この問題の回避するには「[[マイクロソフト サポート技術情報 - 309482>http://support.microsoft.com/default.aspx?scid=kb;JA;309482]]」にある通り、FileStreamオブジェクトを使用して画像を表示します。

#code(vbnet){{
Dim fs As System.IO.FileStream
fs = New System.IO.FileStream("C:\Blue hills.jpg", _
IO.FileMode.Open, IO.FileAccess.Read)
PictureBox1.Image = System.Drawing.Image.FromStream(fs)
fs.Close()
}}

**ピンポイントリンク [#uda45063]

***APIビューアを.NETで使う [#eedc7e60]

#column(注意){{
この記事の最新版は「[[.NET用のAPIビューア>http://dobon.net/vb/dotnet/links/apiviewer.html]]」で公開しています。
}}

VB6には"APIビューア"(VB 6 API Declaration Loader)というツールがついていました。この"APIビューア"というものはVBでWin32 APIを簡単に使えるようにするためのツールで、APIの定義が書かれたファイルを読み込むことにより、APIの検索とVBで使用する際の記述内容のコピーができるというものです。

この"APIビューア"ですが、.NETではなくなってしまいました。.NETではWin32 APIを使う必要はないと考えたのか、その辺の事情は分かりませんが、.NETになっても相変わらずWin32 APIの必要性がなくなったとは到底思えず、さらに使用する際の宣言のめんどくささも変わっていません。

そこでVB.NET、C#用のAPIビューアがないものかと思い探したところ、"Pramod K. Singh"さん作の"[[API Viewer>http://www.c-sharpcorner.com/Tools/APIViewerPKS.asp]]"というツールを見つけました。この"API Viewer"はVB6の"APIビューア"で使われていた"WIN32API.TXT"を読み込むことにより使用します。VB.NETだけでなく、C#にも対応しており、大変便利です。

以下にWriteFile関数について取得した内容を"APIビューア"を使ったとき、およびこの"API Viewer"を使ったとき(VB.NET、C#)それぞれ載せておきますので、どのような違いがあるかご確認ください。

''APIビューア''

#prescroll(wrap=true){{
Public Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long
}}

''VB.NET''

#prescroll(wrap=true){{
Public Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Integer, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Integer, lpNumberOfBytesWritten As Integer,<MarshalAs(UnmanagedType.Struct)> ByRef   lpOverlapped As OVERLAPPED) As Integer
}}

''C#''

#prescroll(wrap=true){{
[DllImport("kernel32.dll")]
public  static extern int  WriteFile(int  hFile,int  lpBuffer,int  nNumberOfbyte sToWrite,int  lpNumberOfbyte sWritten,[MarshalAs(UnmanagedType.Struct)] ref  OVERLAPPED lpOverlapped);
}}

**コメント [#k37028f6]
#comment

//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2010-03-20 (土) 01:45:23,DOBON!,2010-03-20 (土) 01:45:23,DOBON!)
[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]