.NETプログラミング研究 創刊号 †
ご挨拶 †
はじめまして、こんにちは。「.NETプログラミング研究」発行人の「どぼん!」です。よろしくお願いいたします。
この「.NETプログラミング研究」ではMicrosoft .NET Frameworkに関するプログラミング情報(主にVisual Basic .NETとC#)を紹介することを目的とします。私一人で作成しているメールマガジンのため、たいしたことはできないかもしれませんが、末永くご購読いただければ幸いです。
次にそれぞれの項目について簡単にその趣旨を説明させていただきます。
- .NET Tips
- Microsoft .NET Frameworkに関するTipsを紹介します。
- VBユーザーのためのC#
- VBユーザーがC#を使う際に役立つ情報を紹介します。
- .NET質問箱
- 私が管理人をしているサイト「どぼん!のVB道」(https://dobon.net/vb)の掲示板に寄せられた質問とその答えを紹介します。
- ピンポイントリンク
- インターネットでは.NETプログラミングに役立つすばらしいTipsやサンプル、ツールなどがたくさん紹介されています。ここでは「○○するにはどうすればいいのか?」といった個々の問題についての解決に役立つページを紹介させていただきます。
.NET Tips †
ファイルを関連付けられたソフトで開いて終了まで待機する †
ファイルを関連付けられたソフトで開くには次のようにProcessクラスのStartメソッドを使用します。
1
| | System.Diagnostics.Process.Start("C:\test.txt")
|
さらに終了まで待機するには次のようにProcessクラスのWaitForExitメソッドを使用します。このとき同期的に待機するため待機中はフリーズしたようになります。
1
2
3
4
5
6
7
| | Dim objProcess As System.Diagnostics.Process = _
System.Diagnostics.Process.Start("C:\test.txt")
objProcess.WaitForExit()
MsgBox("終了。")
|
次の例ではプロセスの終了まで非同期的に待機します。Button1をクリックしてメモ帳を起動し、メモ帳が終了するとOnExitedが呼び出されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| | 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")
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# †
VBのSplit関数と同じことをするには? †
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よりも倍以上速く処理できました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| | 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;
t1 = System.Environment.TickCount;
s1 = System.Text.RegularExpressions.Regex.Split(strText,
"\r\n");
t1 = System.Environment.TickCount - t1;
t2 = System.Environment.TickCount;
s2 = Microsoft.VisualBasic.Strings.Split(strText, "\r\n", -1,
Microsoft.VisualBasic.CompareMethod.Binary);
t2 = System.Environment.TickCount - t2;
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);
|
.NET質問箱 †
Q:表示中の画像ファイルが削除できません! †
A:「画像ファイルを表示」で紹介したFromFileメッソドを使用して画像を表示した時や、PictureBox コントロールのImageプロパティをデザイン時に手動でファイルに設定した時は、その画像ファイルがロックされてしまい、削除する事が出来なくなります(「画像ファイルを表示」の例では"C:\Blue hills.jpg"が削除できません)。この問題の回避するには「マイクロソフト サポート技術情報 - 309482」にある通り、FileStreamオブジェクトを使用して画像を表示します。
1
2
3
4
5
| | 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()
|
ピンポイントリンク †
APIビューアを.NETで使う †
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"というツールを見つけました。この"API Viewer"はVB6の"APIビューア"で使われていた"WIN32API.TXT"を読み込むことにより使用します。VB.NETだけでなく、C#にも対応しており、大変便利です。
以下にWriteFile関数について取得した内容を"APIビューア"を使ったとき、およびこの"API Viewer"を使ったとき(VB.NET、C#)それぞれ載せておきますので、どのような違いがあるかご確認ください。
APIビューア
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
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#
[DllImport("kernel32.dll")]
public static extern int WriteFile(int hFile,int lpBuffer,int nNumberOfbyte sToWrite,int lpNumberOfbyte sWritten,[MarshalAs(UnmanagedType.Struct)] ref OVERLAPPED lpOverlapped);
|
コメント †