http://msdn.microsoft.com/ja-jp/library/cc364423.aspx を見てもWindowsキーがどういう文字列を送ればいいのか載っていない。
いろいろ調べ回ってようやく分かった。
「Windows」キーは「CTRL」+「ESC」キーの組み合わせだった。
つまりCTRLキーは「^」でESCキーは「{ESC}」なので、SendKeys.Send("^{ESC}") となる。
2012年11月28日
2012年09月11日
32/64bit両方でネイティブに動作するプログラムを作る
今まで32bitか64bitか意識しなくてもちゃんと64bit版OSで動いていたのだが、ある時レジストリの編集をしていてどういうわけか64bit版Windows7で更新されていないのに気が付いた。全てのレジストリではない、ある特定のレジストリである。なぜ更新されないのか調べていくうちに、意外なことが判った。
実は更新されていないのではなく、別のところに更新されていたのだ。
もともと更新したかったのは
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.....だった。
ところが実際に更新されていたのは
\HKEY_LOCAL_MACHINE\Wow6432Node\SOFTWARE\Microsoft\.....だった。
原因はプログラムが32bit用アプリケーションだったためだった。
このレジストリはどうやら64bit用アプリでないと本来の場所に書き込まないらしい。
そこで64bit用にコンパイルし直す必要が出てきたのだが、32bitと64bit別々に作るのは煩わしい。
調べてみると両方で動作するコンパイル方法があることが判った。
ビルドメニューの「構成マネージャ」からプラットフォームで「Any CPU」を指定すればいいのである。

64bit対応アプリの作成方法の参考ページ
http://code.msdn.microsoft.com/windowsdesktop/10-64-NET-VB-ae70ffc1
ここには以下の表が掲載されている。これで一目瞭然。

実は更新されていないのではなく、別のところに更新されていたのだ。
もともと更新したかったのは
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.....だった。
ところが実際に更新されていたのは
\HKEY_LOCAL_MACHINE\Wow6432Node\SOFTWARE\Microsoft\.....だった。
原因はプログラムが32bit用アプリケーションだったためだった。
このレジストリはどうやら64bit用アプリでないと本来の場所に書き込まないらしい。
そこで64bit用にコンパイルし直す必要が出てきたのだが、32bitと64bit別々に作るのは煩わしい。
調べてみると両方で動作するコンパイル方法があることが判った。
ビルドメニューの「構成マネージャ」からプラットフォームで「Any CPU」を指定すればいいのである。
64bit対応アプリの作成方法の参考ページ
http://code.msdn.microsoft.com/windowsdesktop/10-64-NET-VB-ae70ffc1
ここには以下の表が掲載されている。これで一目瞭然。
2012年09月07日
起動時にフォームを表示せず、タスクトレイ(通知領域)にアイコン表示させる
ずっと以前「VB.NETではForm1(最初に起動させるフォーム)を非表示で起動できない?」というTipsを紹介した。ところがVB2010ではこの方法でもフォームが小さく表示してしまうことが判明、別の対策をすることになった。
今回の見つけた方法はvb2005〜2010全てで動作する。(初期vb.netやvb2003は開発環境が無いため確認不能)
デザイン時のForm1のプロパティ設定は以下の3つ
・Opacity = 0
・ShowInTaskbar = False
・WindowState = Minimized 'これはForm_Loadイベント内でも可
実行時のイベントでの処理
このTipsの肝要はOpcityの使用である。コントロールの不透明度を利用して見えなくするのだ。
今回の見つけた方法はvb2005〜2010全てで動作する。(初期vb.netやvb2003は開発環境が無いため確認不能)
デザイン時のForm1のプロパティ設定は以下の3つ
・Opacity = 0
・ShowInTaskbar = False
・WindowState = Minimized 'これはForm_Loadイベント内でも可
実行時のイベントでの処理
Private Sub NotifyIcon1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles NotifyIcon1.Click
Me.WindowState = FormWindowState.Normal
End Sub
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Resize
If Me.WindowState = FormWindowState.Minimized Then
Me.Opacity = 0
Else
Me.Opacity = 100
End If
End Sub
このTipsの肝要はOpcityの使用である。コントロールの不透明度を利用して見えなくするのだ。
2012年08月16日
Windows7 + Visual Basic 2010 でサービスプログラムの開発覚書
以前VB2005でサービスプログラムを作ったことがある。その時にデバッグについてのTipsを書いたが今回はそれ以前のサービスとして動作させるための初歩的な躓きについてのTipsである。
今回VB2010用の参考書「Visual Basic 2010 逆引き大全555」を使ってサンプルをテストした。
サンプルをそのままビルドし、InstallUtilを使いインストールしてちゃんと登録されている。(下図)


ここで「開始」を選択するが「サービスを開始できません」と下図のようなエラーになる。


何がいけないのか散々調べてようやく判ったのは、実行させているプログラムのあるフォルダのアクセス権にサービスの実行アカウントに指定した「Local Service」が無いからだった。(下図)

これを割り当てることで無事サービスが開始された。(下図)

今回VB2010用の参考書「Visual Basic 2010 逆引き大全555」を使ってサンプルをテストした。
| Visual Basic 2010逆引き大全555の極意―Windows 7/Vista完全対応 | |
![]() | 池谷 京子 国本 温子 増田 智明 秀和システム 2010-11 売り上げランキング : 43124 Amazonで詳しく見るby G-Tools |
サンプルをそのままビルドし、InstallUtilを使いインストールしてちゃんと登録されている。(下図)
ここで「開始」を選択するが「サービスを開始できません」と下図のようなエラーになる。
何がいけないのか散々調べてようやく判ったのは、実行させているプログラムのあるフォルダのアクセス権にサービスの実行アカウントに指定した「Local Service」が無いからだった。(下図)
これを割り当てることで無事サービスが開始された。(下図)
2011年09月09日
VS2005からSQLServer2008R2に接続できない
VB2005の開発環境でサーバーエクスプローラを開き、SQLServer2008R2を稼動しているPCに接続しようとしたところ「接続の確認」ボタンでは問題なかったのに「OK」ボタンをクリックした途端、下図のようなエラー「このバージョンのサーバーはサポートされていません・・・」が発生した。

今までバージョンが違っても使えたと思ったのに変だ・・・と思って調べたところパッチが出ていることを知った。
「Microsoft SQL Server 2008 サポート用 Microsoft Visual Studio 2005 Service Pack 1 更新プログラム 」
今までバージョンが違っても使えたと思ったのに変だ・・・と思って調べたところパッチが出ていることを知った。
「Microsoft SQL Server 2008 サポート用 Microsoft Visual Studio 2005 Service Pack 1 更新プログラム 」
2011年09月05日
Windows CE のデバッグができなくなった理由
Visual Studio 2005 を使って Windows CE の開発を続けていたのだが、途中でVS2008,VS2010の開発環境を導入したところ、いつのまにかWindows CEのデバッグ時にActiveSyncで繋がれた端末側でエラーが発生しデバッグが出来なくなってしまった。
あれこれ調査した結果、プロジェクトのプロパティの「デバイス」にある「配置オプション」の「Service Pack を含む最新バージョンの .NET Compact Framework を配置」を無効にすると正常にデバッグできようになった。
以前はVS2005だけの環境だったので有効になっていても問題が起きなかっただけだと分かった。
あれこれ調査した結果、プロジェクトのプロパティの「デバイス」にある「配置オプション」の「Service Pack を含む最新バージョンの .NET Compact Framework を配置」を無効にすると正常にデバッグできようになった。
以前はVS2005だけの環境だったので有効になっていても問題が起きなかっただけだと分かった。
2011年08月01日
IPアドレスの取得時の注意
FTPクライアントを作った時、WindowsXPの開発環境では問題なく動作していたのが、本番環境のWindowsServer2008ではハングアップしてしまった。最初はファイヤーウォールが問題かと考えいろいろ設定したのだが一向に解消されない。
仕方なく本番環境と同じWindowsServer2008にVisualStudioをインストールして動作確認したところ、やっと原因が判明した。
問題は自分のIPアドレスを取得する際の Dns.GetHostEntry(Dns.GetHostName()).AddressList(0) に問題があった。
XPまでなら、IPアドレスはIPv4つまり、192.168.0.0などで表現されるIPアドレスが取得されるが、Vista以降ではネットワークアダプタにIPv6のインターネットプロトコルが標準で有効になっているのでAddressList(0)ではIPv4ではなくIPv6のアドレスが取得されてしまうからだった。
そこでIPv4を確実に取得するように以下の修正が必要になる。
(Imports System.Net を忘れずに)
AddressFamilyを調べることでIPv4かIPv6か判定できる。
・IPv4=Sockets.AddressFamily.InterNetwork
・IPv6=Sockets.AddressFamily.InterNetworkV6
仕方なく本番環境と同じWindowsServer2008にVisualStudioをインストールして動作確認したところ、やっと原因が判明した。
問題は自分のIPアドレスを取得する際の Dns.GetHostEntry(Dns.GetHostName()).AddressList(0) に問題があった。
XPまでなら、IPアドレスはIPv4つまり、192.168.0.0などで表現されるIPアドレスが取得されるが、Vista以降ではネットワークアダプタにIPv6のインターネットプロトコルが標準で有効になっているのでAddressList(0)ではIPv4ではなくIPv6のアドレスが取得されてしまうからだった。
そこでIPv4を確実に取得するように以下の修正が必要になる。
(Imports System.Net を忘れずに)
Dim ipa As IPAddress
Dim iphEntry As IPHostEntry = Dns.GetHostEntry(Dns.GetHostName())
For Each ipAddr As IPAddress In iphEntry.AddressList
If ipAddr.AddressFamily = Sockets.AddressFamily.InterNetwork Then
ipa = ipAddr
Exit For
End If
Next
AddressFamilyを調べることでIPv4かIPv6か判定できる。
・IPv4=Sockets.AddressFamily.InterNetwork
・IPv6=Sockets.AddressFamily.InterNetworkV6
2011年07月27日
Windows CE プログラムのバージョン取得
今Windows CE のアプリを作っているのだが、自アプリのバージョン(アセンブリバージョンのみ有)を取得しようとして、従来の一般アプリの方法「自アプリケーションのバージョンを取得」が使えないのに気が付いた。
調べてみたら全く知らない方法で取得することが判った。
これはMicrosoftの.NET Compact Framework に関するよくある質問サイトで見つけた。
「.NET Compact Framework 内のファイルのバージョンを確認できますか」
調べてみたら全く知らない方法で取得することが判った。
Dim ver As String = _
System.Reflection.Assembly.GetExecutingAssembly.GetName.Version.ToString
これはMicrosoftの.NET Compact Framework に関するよくある質問サイトで見つけた。
「.NET Compact Framework 内のファイルのバージョンを確認できますか」
2010年12月06日
Crystal Reports for Visual Studio 2010 正規版が公開
ようやくベータ版から正規版となり、日本語環境で使えるようになった。
それにしても、VS2010(日本語版)が発売されてから、半年遅れでようやく使えるようになるというのはどういうことだろうか。結局VS2008で開発せざるをえなかった。
Crystal Reportsは旧Visual Basic5/6時代からバンドルされている名レポートツールだが、たびたび提供する会社が変わった。この際Microsoftが自社製品として買収すればいいんだ。





インストール完了後、レポートを追加するとウィザードが起動した。

それにしても、VS2010(日本語版)が発売されてから、半年遅れでようやく使えるようになるというのはどういうことだろうか。結局VS2008で開発せざるをえなかった。
Crystal Reportsは旧Visual Basic5/6時代からバンドルされている名レポートツールだが、たびたび提供する会社が変わった。この際Microsoftが自社製品として買収すればいいんだ。
インストール完了後、レポートを追加するとウィザードが起動した。
2010年07月06日
Crystal Reports for Visual Studio 2010 Beta版は英語版なら起動する
前回「Crystal Reports for Visual Studio 2010 Beta版は日本語環境では使えない」ということを書いたが、本当にそうだろうか?何か設定が足りないから動かないんじゃないか?という疑問が消えなかった。
そこで実際に英語版で同じ手順でインストールすれば使えるかどうかを確かめることにした。
英語版WindowsXP(Pro)上に英語版VS2010(Pro)をインストールしてみたのが下の図だ。

そして同じように「cr4vs2010.exe」をダウンロードしてインストールした。(下図)

VS2010を再起動してレポートファイル(rpt)を追加したところ、間違いなくrptファイルが作成され、ウィザードが起動した。(下図)
やはり日本語環境ではベータ版は使えないことが判った。

提供元のSAPのアナウンスによると、現在のベータ版はベータ1で8月上旬にはベータ2を提供し、製品版は11月になるという。ベータ2に各国語版が含まれれば良いが、さもないとVS2010での開発は諦めてVS2008を使うしかないかもしれない。続きを読む
そこで実際に英語版で同じ手順でインストールすれば使えるかどうかを確かめることにした。
英語版WindowsXP(Pro)上に英語版VS2010(Pro)をインストールしてみたのが下の図だ。
そして同じように「cr4vs2010.exe」をダウンロードしてインストールした。(下図)
VS2010を再起動してレポートファイル(rpt)を追加したところ、間違いなくrptファイルが作成され、ウィザードが起動した。(下図)
やはり日本語環境ではベータ版は使えないことが判った。
提供元のSAPのアナウンスによると、現在のベータ版はベータ1で8月上旬にはベータ2を提供し、製品版は11月になるという。ベータ2に各国語版が含まれれば良いが、さもないとVS2010での開発は諦めてVS2008を使うしかないかもしれない。続きを読む
2010年06月28日
Crystal Reports for Visual Studio 2010 Beta版は日本語環境では使えない
VS2008まではProfessional版以降ではCrystalReportsは標準でバンドルされていたが、VS2010になって別サイトからダウンロードするようになった(下図)

しかし、まだベータ版ということになっている。そのためかダウンロードした「cr4vs2010.exe」をインストールしてもrptファイルが作成されず、最初と同じサイトへのリンクファイル(mht)になってしまう。(下図)

フォーラム(英語)をネット翻訳で調べたところ、どうやらベータ版は英語仕様でしか動かないらしい。(確かに解凍されたセットアップのlangsフォルダにはenフォルダしか無かった)
「Crystal Reports for Visual Studio 2010 Beta版は英語版なら起動する」
正規版で各国語対応になるまで待てということらしい。
※ダウンロードサイトには正規版の公開は7月予定と記載されていた。
2010年7月6日現在、以下のように変更されていた。(訳はネット翻訳による)
「ベータ1は現在利用可能です。ベータ2は8月上旬、製品版は11月の予定です。」
ベータ2に日本語版が含まれていれば良いが、無ければVS2008で開発しないと納期に間に合わないかも・・・・。続きを読む
しかし、まだベータ版ということになっている。そのためかダウンロードした「cr4vs2010.exe」をインストールしてもrptファイルが作成されず、最初と同じサイトへのリンクファイル(mht)になってしまう。(下図)

フォーラム(英語)をネット翻訳で調べたところ、どうやらベータ版は英語仕様でしか動かないらしい。(確かに解凍されたセットアップのlangsフォルダにはenフォルダしか無かった)
「Crystal Reports for Visual Studio 2010 Beta版は英語版なら起動する」
正規版で各国語対応になるまで待てということらしい。
※ダウンロードサイトには正規版の公開は7月予定と記載されていた。
2010年7月6日現在、以下のように変更されていた。(訳はネット翻訳による)
「ベータ1は現在利用可能です。ベータ2は8月上旬、製品版は11月の予定です。」
ベータ2に日本語版が含まれていれば良いが、無ければVS2008で開発しないと納期に間に合わないかも・・・・。続きを読む
2010年06月22日
フォームデザイン時の補助線が消えた
2010年03月08日
WebBrowserの印刷プレビュー画面が異様に小さい
WindowsアプリでHTMLを表示するのにWebBrowserコントロールが使えるが、これをデザイン時にフォームに配置した場合、印刷プレビューは特に問題なく表示するのだが、コードで動的に作成した場合、印刷プレビュー画面が異様に小さくなる(下図参照)

これを何とかしようとWidth,Heightプロパティを指定してみたが一向に直らない。
あれこれ調べまわった挙句、ようやく判った。
デザイン時にコントロールを貼り付けた場合、印刷プレビュー画面は元(親)のフォームと同じサイズで表示される。これがミソだ。親コンテナと同じサイズで表示される仕様らしい。
というわけで、Parentプロパティに親フォーム名または単にMeを指定すれば良いのだ。
WebBrowser.Parent = Me
WebBrowser.ShowPrintPreviewDialog()

これを何とかしようとWidth,Heightプロパティを指定してみたが一向に直らない。
あれこれ調べまわった挙句、ようやく判った。
デザイン時にコントロールを貼り付けた場合、印刷プレビュー画面は元(親)のフォームと同じサイズで表示される。これがミソだ。親コンテナと同じサイズで表示される仕様らしい。
というわけで、Parentプロパティに親フォーム名または単にMeを指定すれば良いのだ。
WebBrowser.Parent = Me
WebBrowser.ShowPrintPreviewDialog()
2010年03月06日
メールの日付ヘッダの相互変換
メールの送受信プログラムを作る時、メール日付の変換に苦労した。
ヘッダの日付情報は文字列であり、それをDate(DateTime)型に変換するにはどうすれば良いのか。また現在日時(Date型)をヘッダ書式に変換するにはどうすれば良いのか。
以下にまとめておく。
ヘッダの日付情報は文字列であり、それをDate(DateTime)型に変換するにはどうすれば良いのか。また現在日時(Date型)をヘッダ書式に変換するにはどうすれば良いのか。
以下にまとめておく。
'//// メール形式の日付を日付型(ローカル時間)に変換 ////
Public Function DateHeader_ToDate(ByVal strdate As String) As Date
'-----------------------------------------------------
' 引数:strdate メールヘッダの日付文字列
'(書式:曜日, 日 月 年 時:分:秒 TimeZone)
'-----------------------------------------------------
Dim wkArray() As String 'ヘッダの文字列の配列
Dim in_date As Date 'ヘッダの日時
Dim interval_hour As Single 'ヘッダのローカル(日本)時間との時差
'半角スペースが2個つながる部分は1つにする
strdate = Replace(strdate, Chr(32) & Chr(32), Chr(32))
'改行以降は削除
If InStr(strdate, Chr(10)) > 0 Then
strdate = Left(strdate, InStr(strdate, Chr(10)))
End If
'半角スペースをキーに配列に保存
wkarray = Split(strdate, Chr(32))
'ヘッダ日時を取得
Dim utcOffset As TimeSpan = TimeZone.CurrentTimeZone.GetUtcOffset(Now)
Select Case wkarray.Length
Case 6, 7 '曜日を含んだ日付文字列の場合
If InStr(wkarray(0), ",") > 0 Then
in_date = Format(wkarray(1) & "-" & _
wkarray(2) & "-" & _
wkarray(3) & " " & _
wkarray(4))
'ローカル(日本)時間との時差を取得
interval_hour = utcOffset.TotalHours - CInt(wkarray(5)) * 0.01
End If
Case 5 '曜日が無い日付文字列の場合
If InStr(wkarray(0), ",") = 0 Then
in_date = Format(wkarray(0) & "-" & _
wkarray(1) & "-" & _
wkarray(2) & " " & _
wkarray(3))
'ローカル(日本)時間との時差を取得
interval_hour = utcOffset.TotalHours - CInt(wkarray(4)) * 0.01
End If
End Select
'ローカル時間に修正
Return DateAdd(DateInterval.Hour, interval_hour, in_date)
End Function
'//// 日付型データをメール形式に変換 ///////
Public Function Date_ToDateHeader(ByVal d As Date) As String
'd : 対象日時
'-------------
'UTC(世界協定時刻)とのオフセットを求める
Dim utcOffset As TimeSpan = TimeZone.CurrentTimeZone.GetUtcOffset(Now)
'オフセットを分数に変更
Dim Jisa As Long = utcOffset.TotalMinutes
'オフセット時間は以下のようにしても求められる
'Dim Jisa As Long = DateDiff(DateInterval.Minute, d.ToUniversalTime, d)
'オフセットを「+0900」書式に変換
Dim strJisa As String = IIf(Math.Sign(Jisa) >= 0, " +", " -") & _
(Math.Abs(Jisa) \ 60).ToString("00") & _
(Math.Abs(Jisa) Mod 60).ToString("00")
'メール日付に整形(英語表記のためカルチャーを変更)
Dim cultureUS As New System.Globalization.CultureInfo("en-us")
Return d.ToString("ddd, dd MMM yyyy HH:mm:ss", cultureUS) & strJisa
End Function
2010年02月22日
ListViewコントロールで各列ヘッダをクリックしてソートさせる
ListViewの列ヘッダをクリックしてソートさせる方法はヘルプにも書かれているが、クリックする度に昇順・降順を切り替える方法が書かれていない。そこでいろいろ調べてようやく見つけた方法を紹介する。
降順にするには マイナスを付けるだけだったとは知らなかった。
'フォームのカラムクリックイベント
Private Sub ListView1_ColumnClick(ByVal sender As Object, _
ByVal e As System.Windows.Forms.ColumnClickEventArgs) _
Handles ListView1.ColumnClick
Static no(5) As Integer '列のソート状態保持用
If no(e.Column) = 0 Then
'初回または昇順
Me.ListView1.ListViewItemSorter = New ListViewItemComparer(e.Column, 0)
no(e.Column) = 1 '次回は降順
Else
'降順
Me.ListView1.ListViewItemSorter = New ListViewItemComparer(e.Column, 1)
no(e.Column) = 0 '次回は昇順
End If
End Sub
'ListViewItemComparerクラスをフォームコードに追加
Class ListViewItemComparer
Implements IComparer
Private col As Integer
Private sort As Integer
Public Sub New()
col = 0
sort = 0
End Sub
Public Sub New(ByVal column As Integer, ByVal sortflg As Integer)
'column : 列番号
'sortflg : ソート(0=昇順,1=降順)
'--------------------------------
col = column
sort = sortflg
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
Implements IComparer.Compare
If sort = 0 Then
'昇順
Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, _
CType(y, ListViewItem).SubItems(col).Text)
Else
'降順
Return -[String].Compare(CType(x, ListViewItem).SubItems(col).Text, _
CType(y, ListViewItem).SubItems(col).Text)
End If
End Function
End Class
降順にするには マイナスを付けるだけだったとは知らなかった。
2009年06月06日
サービスプログラムのデバッグ方法(Visual Studio 2005)
Windowsサービスを作成したが、動作がおかしいのでデバッグすることになった。
その時のデバッグ操作が結構てこずったので注意書きとしてまとめておく。
デバッグの方法はWindowsプログラムとはちょっと違う。WindowsプログラムではDebugモードで実行させるだけで済むがサービスプログラムは実際にサービスとして稼動させてから開発ツールでそのプロセスを監視させて行う。
ここで注意すべきなのはWindowsプログラムと同様にビルドの構成をDebugにしておく必要があることだ。(過去ログ:ブレークポイントで止まらないを参照)
サービスプログラムを実行させるには
(Windows)\Microsoft.NET\Framework\(バージョン)\installutil.exe を使ってインストールする必要がある。コマンドプロンプトから実行するので私の場合は、このコマンドだけをサービスプログラムの実行ファイル(exe)のあるフォルダ(bin\debug)にコピーして、そこからインストールしている。
InstallUtil.exe (サービスプログラム名).exe
※Vistaの場合コマンドプロンプトを管理者として実行させておかないとインストールに失敗する。
インストール後、サービスがまだ開始されていないのでコントロールパネルの管理ツールからサービスマネージャを開いて開始させる。
あとはデバッグポイントを設定し、「ツール」メニューにある「プロセスにアタッチ」を開き「選択可能なプロセス」から当サービスプログラムを選択し「アタッチ」ボタンをクリックする。このとき「すべてのユーザーからのプロセスを表示する」と「すべてのセッションのプロセスを表示する」にチェックを入れておかないとサービスプログラムは表示されない。
プロセス一覧には(プログラム名).vshost.exeというファイル名がグレー表示しているが、これはサービスプログラムのプロジェクトを開いている開発ツールのことだ。
なお、上記手順から判るようにサービスプログラムの起動時(OnStartイベント)のデバッグは出来ない。(開始されていないサービスは選択可能なプロセス一覧には表示されず、表示されたときは既にOnStart内のコードは終了しているから)
デバッグで問題点が見つかり修正する場合、一時サービスを停止しておかないとプログラムの置き換えができない。またサービスをアンインストールするときも停止する必要がある。
アンインストールのコマンド以下の通り
InstallUtil.exe /u (サービスプログラム名).exe
その時のデバッグ操作が結構てこずったので注意書きとしてまとめておく。
デバッグの方法はWindowsプログラムとはちょっと違う。WindowsプログラムではDebugモードで実行させるだけで済むがサービスプログラムは実際にサービスとして稼動させてから開発ツールでそのプロセスを監視させて行う。
ここで注意すべきなのはWindowsプログラムと同様にビルドの構成をDebugにしておく必要があることだ。(過去ログ:ブレークポイントで止まらないを参照)
サービスプログラムを実行させるには
(Windows)\Microsoft.NET\Framework\(バージョン)\installutil.exe を使ってインストールする必要がある。コマンドプロンプトから実行するので私の場合は、このコマンドだけをサービスプログラムの実行ファイル(exe)のあるフォルダ(bin\debug)にコピーして、そこからインストールしている。
InstallUtil.exe (サービスプログラム名).exe
※Vistaの場合コマンドプロンプトを管理者として実行させておかないとインストールに失敗する。
インストール後、サービスがまだ開始されていないのでコントロールパネルの管理ツールからサービスマネージャを開いて開始させる。
あとはデバッグポイントを設定し、「ツール」メニューにある「プロセスにアタッチ」を開き「選択可能なプロセス」から当サービスプログラムを選択し「アタッチ」ボタンをクリックする。このとき「すべてのユーザーからのプロセスを表示する」と「すべてのセッションのプロセスを表示する」にチェックを入れておかないとサービスプログラムは表示されない。
プロセス一覧には(プログラム名).vshost.exeというファイル名がグレー表示しているが、これはサービスプログラムのプロジェクトを開いている開発ツールのことだ。
なお、上記手順から判るようにサービスプログラムの起動時(OnStartイベント)のデバッグは出来ない。(開始されていないサービスは選択可能なプロセス一覧には表示されず、表示されたときは既にOnStart内のコードは終了しているから)
デバッグで問題点が見つかり修正する場合、一時サービスを停止しておかないとプログラムの置き換えができない。またサービスをアンインストールするときも停止する必要がある。
アンインストールのコマンド以下の通り
InstallUtil.exe /u (サービスプログラム名).exe
2009年04月21日
VB2005(VB.NET)のNotifyIconからのフォーム表示の問題点
タスクトレイにアイコンを表示させる時、VB6の時はかなり面倒な処理をする必要があったが、VB.NETではNotifyIconコントロールという大変便利なものがある。
今回これを使ったプログラムを作っていて問題が見つかった。
それは、タスクトレイに表示されたアイコンをクリックしてフォームを開くとき、そのままではアクティブになっていないのである。
たとえば、パスワードを入力させるためにパスワード用フォームを開いてもキー入力を受け付けないのである。一回フォームをクリックしてアクティブにしてからでないとキー入力できないというのでは使い勝手が悪い。これが別のフォーム上のButtonコントロールから開くときにはちゃんとアクティブになっているのだから始末が悪い。
何とかアクティブにならないかと悪戦苦闘してみたが100%確実にアクティブにする方法が見つからない。
ところがやっと見つかった解決策は実に単純だった。
フォームのLoadイベントのなかで、Me.Activate() と一行追加するだけで解決した。
やれやれ(^^;
今回これを使ったプログラムを作っていて問題が見つかった。
それは、タスクトレイに表示されたアイコンをクリックしてフォームを開くとき、そのままではアクティブになっていないのである。
たとえば、パスワードを入力させるためにパスワード用フォームを開いてもキー入力を受け付けないのである。一回フォームをクリックしてアクティブにしてからでないとキー入力できないというのでは使い勝手が悪い。これが別のフォーム上のButtonコントロールから開くときにはちゃんとアクティブになっているのだから始末が悪い。
何とかアクティブにならないかと悪戦苦闘してみたが100%確実にアクティブにする方法が見つからない。
ところがやっと見つかった解決策は実に単純だった。
フォームのLoadイベントのなかで、Me.Activate() と一行追加するだけで解決した。
やれやれ(^^;
2006年10月19日
My.Settingsの内容はどこに保存されるのか。
今まで不思議に思っていたのは、app.config内のMySettingsセクションに更新した内容が保存されるのものと思っていたのにファイルのタイムスタンプを見てもインストール時と全く同じままなので一体どこに保存されているのだろうかということだった。
いろいろ調べてみたところ、Documents and Settings\(LoginUser)\Local Settings\Application Data\(会社名)\(アプリ名)\(アセンブリバージョン)\
内にuser.configというファイルに保存されていることが判った。(下図)

user.configのなかみ

※このことで、前Tipsで一部不正確なところがありました。
アセンブリバージョンが変わるとアプリケーション設定(app.config)のMy.Settingsの内容が初期化されると説明しましたが、正しくはアセンブリバージョン別に設定(user.config)が管理されているために結果として初期化され、バージョンを戻すと該当バージョンの設定を再び読み込むようになっています。
いろいろ調べてみたところ、Documents and Settings\(LoginUser)\Local Settings\Application Data\(会社名)\(アプリ名)\(アセンブリバージョン)\
内にuser.configというファイルに保存されていることが判った。(下図)
user.configのなかみ
※このことで、前Tipsで一部不正確なところがありました。
アセンブリバージョンが変わるとアプリケーション設定(app.config)のMy.Settingsの内容が初期化されると説明しましたが、正しくはアセンブリバージョン別に設定(user.config)が管理されているために結果として初期化され、バージョンを戻すと該当バージョンの設定を再び読み込むようになっています。
VB2005 アプリケーション設定(app.config)とアセンブリバージョンの関係
前回、INIファイルに変わる環境設定の保存方法としてMy.Settingsオブジェクトを紹介した。前々回では、自アプリケーションのバージョン取得について紹介した。
今回のTipsでは、この2つのTipsが関係するちょっと困った現象とその回避策をとりあげる。
この現象に気付いたのは出来上がったプログラムを納品したときだった。
バグが見つかったため修正してプログラム本体だけをコピーして起動させたところ、修正箇所とは関係ないところでエラーを起こした。
原因はMy.Settingsオブジェクトで管理している設定内容がきれいさっぱり消えていたためである。なぜクリアされたのか。いろいろ調べた結果アセンブリバージョンを変更するとMy.Settingsの全項目が初期化されることを発見した。さらに、アセンブリバージョン情報にはAssemblyVersionとAssemblyFileVersionの2つがあり後者のAssemblyFileVersionを変更してもMy.Settingsの内容は初期化されないことも判った。
顧客に最新版であることを示す目的でフォームにバージョン情報を表示させているのだが、この情報が前々回Tipsで紹介したMy.Application.Info.VersionではAssemblyVersionの方なのである。このため、バージョンを変更するたびに毎回環境設定を行わなくてはならないことになってしまう。これでは使い勝手が悪すぎるのでフォーム上のバージョンにはAssemblyFileVersionを表示させ、AssemblyVersionは変更しないようにすることにした。
アセンブリ情報ダイアログ

ファイルのプロパティ

サンプルプログラムの画面とソース

今回のTipsでは、この2つのTipsが関係するちょっと困った現象とその回避策をとりあげる。
この現象に気付いたのは出来上がったプログラムを納品したときだった。
バグが見つかったため修正してプログラム本体だけをコピーして起動させたところ、修正箇所とは関係ないところでエラーを起こした。
原因はMy.Settingsオブジェクトで管理している設定内容がきれいさっぱり消えていたためである。なぜクリアされたのか。いろいろ調べた結果アセンブリバージョンを変更するとMy.Settingsの全項目が初期化されることを発見した。さらに、アセンブリバージョン情報にはAssemblyVersionとAssemblyFileVersionの2つがあり後者のAssemblyFileVersionを変更してもMy.Settingsの内容は初期化されないことも判った。
顧客に最新版であることを示す目的でフォームにバージョン情報を表示させているのだが、この情報が前々回Tipsで紹介したMy.Application.Info.VersionではAssemblyVersionの方なのである。このため、バージョンを変更するたびに毎回環境設定を行わなくてはならないことになってしまう。これでは使い勝手が悪すぎるのでフォーム上のバージョンにはAssemblyFileVersionを表示させ、AssemblyVersionは変更しないようにすることにした。
アセンブリ情報ダイアログ
ファイルのプロパティ
サンプルプログラムの画面とソース
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
Label1.Text = "AssemblyVersion : " & _
My.Application.Info.Version.ToString
Label2.Text = "AssemblyFileVersion : " & _
Application.ProductVersion.ToString
End Sub
2006年10月03日
INIファイルに代わるVB2005のアプリケーション設定値の保存
以前に「INIファイルの読み書き」をVB6とVB.NETの比較で紹介したが、VB2005になってこれに代わるとっても楽な方法が追加されたので紹介する。
あまりに楽チンなのでINIファイルを使うことはもう無いだろうと思うほどだ。
VB.NETでもそれに類するものはあったが扱いが面倒だった。それがVB2005になってからは、まるでプロパティを設定するのと同じ感覚でできるのでつい利用したくなってしまう。
1.サンプル画面(TextBoxとCheckBoxの内容を保存)

2.TextBoxのプロパティから(ApplicationSettings)の(PropertyBinding)を選択

3.規定値のTextプロパティのほかいろんなプロパティを保存できる

4.「新規」から設定名(Name)を入力する

5.CheckBoxの場合はCheckedプロパティを指定

6.設定値はapp.configに記録される

以上で設定は完了。ほかに何もしなくとも入力した値は保持され、次回起動時にはちゃんと反映されているという優れものである。
が、従来の「登録」や「キャンセル」ボタンを使う場面もまだ多いので、それに対応させる方法も紹介する。
設定内容をコードで確認するには My.Settingsに続いて設定名を指定する。
My.Settings.txtName
My.Settings.chk20
あまりに楽チンなのでINIファイルを使うことはもう無いだろうと思うほどだ。
VB.NETでもそれに類するものはあったが扱いが面倒だった。それがVB2005になってからは、まるでプロパティを設定するのと同じ感覚でできるのでつい利用したくなってしまう。
1.サンプル画面(TextBoxとCheckBoxの内容を保存)
2.TextBoxのプロパティから(ApplicationSettings)の(PropertyBinding)を選択
3.規定値のTextプロパティのほかいろんなプロパティを保存できる
4.「新規」から設定名(Name)を入力する
5.CheckBoxの場合はCheckedプロパティを指定
6.設定値はapp.configに記録される
以上で設定は完了。ほかに何もしなくとも入力した値は保持され、次回起動時にはちゃんと反映されているという優れものである。
が、従来の「登録」や「キャンセル」ボタンを使う場面もまだ多いので、それに対応させる方法も紹介する。
'/// 登録をクリック ///
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnSave.Click
'-- ここで強制的に登録しなくても終了時に自動で保存される
'My.Settings.Save()
Me.Close()
End Sub
'/// キャンセルをクリック ///
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnCancel.Click
'-- 入力内容を破棄したい場合は、再読込みする
My.Settings.Reload()
Me.Close()
End Sub
設定内容をコードで確認するには My.Settingsに続いて設定名を指定する。
My.Settings.txtName
My.Settings.chk20


