ドリンクバーゲン会場

Install Shieldを使ったインストーラーの作成2011年12月12日 12時10分26秒

Install Shield
今の会社では、出来上がったアプリケーションの配布用プログラムを、
そのままCD等に焼いてフォルダごとコピーする方法をとっていました。

しかし、レジストリ情報を書き換える必要があるプログラムの場合、
こちらで設定を行う必要がでてくるので、
インストーラーで対応したいという要望がでているので、
調べてみました。

VisualStudio2010 Professionalには、Windowsインストーラーと、
InstallShieldが使えるようですが、調べたところ次期バージョンからは、
Windowsインストーラーは搭載しないということらしいので、
InstallShieldを使って、インストーラーを作ってみました。

InstallShieldは初めて使う場合にユーザー登録が必要ということで、
登録処理を行いました。
これは、他の会社で行っていることと大差はありません。

プロジェクトからInstallShieldを選択して、インストーラー作成用のプロジェクトを作ります。
インストーラープロジェクト自体は、通常のアプリケーションのプロジェクト作成と同じですので、
名前や場所、ソリューション名などを記入し作成します。

Project assistantの画面の下にあるアイコンを順番に設定していけば、
インストーラーを作成する準備が整います。
一番左の「Application Information」では、
会社名やアプリケーション名、バージョン情報などを入力します。

「Installation Requirements」では、インストールできるOSを制限したり、
フレームワークなどの必須プログラムの確認を行うかどうかを指定します。

「Installation Architecture」はVisualStudio2010に入っているバージョンでは
使用できないので、飛ばします。

「Application Files」では、インストールするファイルを選択します。
ここでは、プログラムや設定ファイルなどを指定します。
フォルダ単位でも指定できるので、プログラムや設定ファイルなどをまとめている場合には、
フォルダ毎指定することもできます。

「Application Shortcuts」では、ショートカットを作成するファイルを指定します。
通常は起動するプログラムを登録しますが、ツールなどがある場合は、
そのプログラムを追加したり、プログラムごとにスタートメニューやデスクトップ上など、
登録場所の指定も行えます。

「Application Registry」はレジストリ情報を登録します。
ここでは、スタートアップの登録を行っています。

「Installation Interview」では、インストール先の変更や、ユーザー名の入力などを
許可するかどうかを指定します。
現時点では、すべてNoで指定し、変更などは許可しないように指定しています。

以上の設定を行えばインストーラーの作成準備はほぼ終わりです。
ほぼと言っているのは、アシスタント画面では設定できない情報を変更する必要があるためです。

InstallShieldでは、初期設定で言語が英語に設定されているため、このままでは英語でインストーラーが起動します。
海外向けの場合は問題ないですが、国内で使用する場合は日本語の方がわかりやすいのと、英語の設定で
日本語の情報が入っていると、ビルドの際にエラーになるので、会社名などを日本語で指定している場合には、
言語設定を日本語にします。

設定方法ですが、ソリューションエクスプローラーから、「Organaize Your Setup」の「General Information」
を選択します。
「GeneralInformation」の画面の「Setup Language」を日本語に変更します。
これで言語設定が日本語になり、インストーラーを起動した際に日本語で表示されます。

次に設定する必要があるのが、.NETFramewworkなどのインストールプログラムをインストーラーに含めることです。
開発の際に、.NETFrameworkを使って開発することがほとんどですが、インストールするPCに入っていない場合、
自動的にインストールを行うようにすることができます。
特に海外では、インターネットの環境が整っていなかったり、PCがネットワークに接続していない場合もあり、
インストールができない状況に陥るのを回避するために、必ず使用しているフレームワークを設定しておきます。

設定方法ですが、「Specify Application Data」の「Redistributables」を選択します。
「Redistributables」画面が表示されたら、一覧の中から、必要な物にチェックを入れます。
次に、選択したライブラリやフレームワークの「Location」を確認します。
「Needs to be downloaded」と表示されている場合は、インストール用のプログラムが存在しないので、
ビルド時にエラーになります。

マウスの右クリックで「Download Selected item...」を選択すると、ダウンロードされます。
「Installed Locally」と表示がかわればOKです。

以上で設定が完了しましたので、ビルドを行いエラーが出なければ作成されています。

後は、適当なPCでセットアップを実行し問題がないか確認すればOKです。

順番に設定を追加していけば、問題なく作成されると思います。

プログラムが終了しない。2011年10月17日 10時44分11秒

今進めている開発では、起動時にタスクトレイに格納するように指示があり、
設定を追加しました。
追加した内容は、起動時にタスクトレイにアイコンを表示し、画面は最小化して表示はださない。

画面表示はアイコンをダブルクリック。
×では終了せず、最小化にする。
プログラムを終了する際にはアイコンを右クリックして、メニューを表示し、
終了をクリックすることで、プログラムを終了させる。

アイコン起動のプログラムでは、一般的な操作方法だと思います。
設定の仕方はネットに載っていたので、その通りに設定を追加し、テストしてみました。

起動時に最小化したうえで、タスクトレイにアイコンを表示させるには、
「NotifyIcon」コンポーネントを追加し、コンポーネントのIconプロパティにアイコンファイルを選択します。
次にメイン画面のプロパティにある、「WindowState」を「Minimaized」に変更すればOK!

ダブルクリックで画面を表示させる方法ですが、
「NotifyIcon」のプロパティにあるダブルクリックイベントに設定を入れます。

this.Visible = true;
if (this.WindowState == FormWindowState.Minimized)
{
this.WindowState = FormWindowState.Normal;
}
this.Activate();

1行目で画面表示を許可します。
次に最小化の設定になっているか確認し、最小化の状態であれば、ノーマルに変更しています。
最後にフォームをアクティブにすることで、画面が表示されます。


「×」で最小化させるには、「FormClosing」イベントで終了処理をキャンセルし、最小化の指定を設定します。
終了処理のキャンセルは、

e.Cancel = true;
this.Visible = false;

上記の2行を追加することで、最小化の指定となります。
上の行が終了処理をキャンセルする処理で
下の処理が、画面を最小化する処理になります。

最後にプログラムを終了させる処理を追加します。
まず、「ContextMenuStrip」を追加し、「終了」の項目を入力します。
入力した「終了」をダブルクリックして、そこに終了の処理を追加します。

notifyIcon1.Visible = false;
Application.Exit();

上記の2行を追加します。
上の行は、タスクトレイに表示されているアイコンを消すための設定です。
これは、終了時にアイコンだけ表示が残ることを防ぐためのものです。
下の行がプログラムを終了するための処理になります。

これらの設定を追加し、実際にテストを行ってみました。

起動時にアイコンのみ表示し、ダブルクリックで画面の表示を行い、
×で最小化とここまでは、順調にいきました。
しかし、最後の終了処理で、アイコンは消えているのに、プログラムが終了しないという状況になりました。

当初はアイコンが消えていたので、プログラムも終了しているのかと思っていたのですが、
VisualStudioが実行中のままになっていたので、おかしいなぁと思っていました。
サーバーとの通信プログラムなので、サーバー側から通信してみると、たしかに動いているようです。
アイコンは消えているけどプログラム自体は終了していませんでした。

いろいろ調べてみると、終了に関しては確実ではないようでした。
別の終了方法がないか確認して終了処理を変更しました。

notifyIcon1.Visible = false;
System.Environment.Exit(1);

「Application.Exit();」を「System.Environment.Exit(1);」に変更したところ、
無事に終了させることができました。
掲示板などでは、使わない方が良いとかかれている方もいらっしゃったのですが、
とりあえず、終了できないと話にならないので、とりあえずこれで様子を見てみようと思います。

VB.NETでのフォーム最大化2011年06月07日 13時41分41秒

VB.NETで作成しているプログラムで、フォームの最大化をさせたときに、
実行させたい処理があり、「MaximumSizeChanged」イベントを使って、
プログラムを作成させました。

しかし、最大化ボタンをクリックしてもその処理が動いた様子がなく、
ブレイクポイントを貼って確かめたところ、何も処理されていませんでした。

もともとは最大化の処理は無効にしていたのですが、最大化できる方が便利
と思い、機能を追加しようとしたら、今の状況になってしまいました。

「MaximumSizeChanged」ってフォームの最大化とは関係ないんでしょうか?

グラフ表示でのちらつきの解消方法2011年05月19日 17時39分40秒

現在、VB.NETでグラフを表示するプログラムを作成しています。
PictureBoxに線や文字を書きこんで表示させるのですが、
タイマーで定期的に更新する際に、画面がちらつく状態になってしまいました。

********************************************
'PictureBoxと関連付け
Dim pic As Graphics = PictureBox1.CreateGraphics()

'画面クリア
pic.Clear(Color.White)

ここに書込み処理が入ります。
*********************************************

ピクチャーボックスにダイレクトに書込みをしていたため、
新しいグラフの描画の前に画面をクリアしていたのですが、それがちらつきの原因でした。
そこで、ちらつかないようにバッファに書込みを行いそのデータをPictureBox
に表示させるように修正しました。

*********************************************
'グラフ用のバッファエリアを作成
Dim bmpbuf As Bitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
Dim pic As Graphics = Graphics.FromImage(bmpbuf)

'画面クリア
pic.Clear(Color.White)

ここに書込み処理が入ります。

'バッファからPictureBoxにコピー
Me.PictureBox1.Image = bmpbuf
*********************************************

変更点は、Pictuirebox1と同じサイズのビットマップを作成し、
ビットマップと関連付けをしたことと、
描画が終わった後PictureBoxにコピーしたことです。

これだけで、ちらつきなくグラフが更新されるようになります。

サブルーチンから複数の値を取得する2011年01月25日 09時50分18秒

今回はサブルーチンから、複数の値を取得したいと思います。
現在、定期試験の採点に関するプログラムを作成中で、
前回は平均を求めたのですが、今必要なのは平均点だけでなく、
合計点も必要になります。

平均点と合計点は、関数以外は違いがないので、平均点と合計点を一度に求め、
それを取得します。

データ取得の部分をサブルーチン化し、合計と平均を取得していきます。

採点テーブル
学籍 科目 点数
A01 国語 75
A01 数学 77
A01 英語 48
A02 国語 48
A02 数学 55
A02 英語 48

前回平均点を求める際に使ったテーブルです。
平均を求めるSQLは次のようなものです。

SELECT ROUND(AVG(CAST(点数 as decimal(3,1))),1) as 平均
from 採点テーブル where 学籍 = 'A01'

今回は合計も求めるので、以下のように修正します。

SELECT ROUND(AVG(CAST(点数 as decimal(3,1))),1) as 平均 , SUM(点数) as 合計
from 採点テーブル where 学籍 = W_GAKUSEKI

これで、合計と平均を出力します。

前回は学籍を直接指定していたのですが、
今回は学籍を変数にし、メインから引き渡します。

メインのプログラムです。

Dim w_dt As Object
Dim wret_cd as integer
Dim wgokei as integer
DIm wheikin as decimal

w_dt = data_set("A01")
wret_cd = wgh(0)
wheikin = wgh(1)
wgokei = wgh(2)

サブのプログラムです。

Private function data_set(W_GAKUSEKI as string) As Object
dim WSQL as String
dim ret(2) as Object

WSQL = "SELECT ROUND(AVG(CAST(点数 as decimal(3,1))),1) as 平均 , SUM(点数) as 合計 from 採点テーブル where 学籍 = '" & W_GAKUSEKI & "'"

Dim cnStr As String = System.Configuration.ConfigurationManager.ConnectionStrings("GAKUSEKI").ConnectionString
Using connection As New SqlConnection(cnStr)
Dim command As New SqlCommand(WSQL, connection)
connection.Open()
Try
Dim dr As SqlDataReader = command.ExecuteReader
If dr.Read Then
ret(0) = 0
ret(1) = dr("平均")
ret(2) = dr("合計")
End If
Catch ex As Exception
ret(0) = -99
End Try
'コネクションを閉じる
connection.Close()
End Using
Return ret
End Function

データベースの接続はサブで行っています。
学籍を取得しSQL文を作成して、読み込んだ結果をretに入れ、
メインに返しています。

これでそれぞれの値を取得することができます。
実際にはエラーチェックなどが入りますが!
複数の項目を返す場面はたくさん出てくるので、
とりあえず、やり方は覚えておいたほうが良いと思います。