VB6から.net Frameworkに移行
現在でも需要があるかわからないですが、VB6で作成されたのシステムを.net Frameworkに移行する必要があったので、メモを残します。以下、移行に際してVB6で作成されたソースコードがあることが前提となります。
移行についてのアイデア
移行の方法ですが、過去にはVB6で作成したソースコードから自動で変換するツールもあったのですが、経験上、変換制度が良くなく大量に事後修正をする必要があり、あまり効率が良くないのがネックでした。そこで、独自にVB6で作成したソースコードをVB.netのソースコードに変換するプログラムを作成し利用することにします。.net FrameworkにはC#を使うという方法もありますが、VB6と文法が近いVB.netを変換先に選択しています。
VB6の拡張子
VB6ですが、代表的なファイルの拡張子に以下のようなものがあります。
.vbp プロジェクトファイル ・・・ 今回は使用しません
.vbw プロジェクトワークスペースファイル ・・・ 今回は使用しません
.bas 標準モジュール
.frm フォームモジュール
.frx バイナリフォーム
他にも多数の拡張子がありますが、使用頻度は少ないと思いますので、説明を割愛します。
まず、.basファイルですが、標準モジュールになりますが、同様の機能がVB.netにもあるので、そのまま移行します。
.frmですが、Windows Formsのフォームに変換します。.frmの中に何が記述されているかですが、前半部分がコントロールのデザイン情報、後半はコントロールイベントに対応するプログラムが記述されています。
.frmファイルの仕様を確認
.frmファイルの仕様ですが、前半部分は以下の様になっています。
Begin VB.Form form1
BorderStyle = 1 '固定(実線)
Caption = "メイン"
ClientHeight = 3015
ClientLeft = 45
ClientTop = 615
ClientWidth = 5640
Icon = "form1.frx":0000
LinkTopic = "Form1"
MaxButton = 0 'False
ScaleHeight = 3015
ScaleWidth = 5640
StartUpPosition = 2 '画面の中央
Begin VB.CommandButton button1
Caption = "ボタン1"
BeginProperty Font
Name = "MS Pゴシック"
Size = 9.75
Charset = 128
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 975
Left = 3720
Picture = "form1.frx":3C1A
Style = 1 'グラフィックス
TabIndex = 8
Top = 1920
Width = 1815
End
これを見ると分かるように "Begin xxx yyy" で始まって"End"で終わるというような入れ子構造になっています。Beginの後にはコントロールの型と名前が続いています。これを見てVB.netへの変換処理の判別を行います。
コントロールの判別
処理の判別の例を一部ご紹介します。
Begin VB.Form -> System.Windows.Forms.Form
Begin VB.CommandButton -> System.Windows.Forms.Button
Begin VB.TextBox -> System.Windows.Forms.TextBox
Begin VB.Label -> System.Windows.Forms.Label
Begin VB.CheckBox -> System.Windows.Forms.CheckBox
Begin VB.ComboBox -> System.Windows.Forms.ComboBox
Begin VB.Menu -> System.Windows.Forms.MenuStrip
フォームの場合
VB.Formについては、フォームの基本になるところなので、フォームを定義するおまじないを沢山指定する必要があります。
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class sample
Inherits System.Windows.Forms.Form
'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Windows フォーム デザイナーで必要です。
Private components As System.ComponentModel.IContainer
'メモ: 以下のプロシージャは Windows フォーム デザイナーで必要です。
'Windows フォーム デザイナーを使用して変更できます。
'コード エディターを使って変更しないでください。
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
''''''この後に各コントロールの処理を記述します''''''
各コントロールの変換例
VB.TextBoxやVB.Labelなどは同名のコントロールがあるので、それを使用します。プロパティも同様に対応します。
例えば、以下のようなTextBoxがあった場合、の変換例を示します。
Begin VB.TextBox text1
BeginProperty Font
Name = "MS Pゴシック"
Size = 9.75
Charset = 128
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 300
IMEMode = 4 '全角ひらがな
Left = 1080
MaxLength = 60
TabIndex = 3
ToolTipText = "あいうえお"
Top = 600
Width = 3735
End
Me.text1 = New System.Windows.Forms.TextBox()
Me.text1.Name = "text1"
Me.text1.ImeMode = System.Windows.Forms.ImeMode.Hiragana
Me.text1.MaxLength = 60
Me.text1.Size = New System.Drawing.Size(249, 20)
Me.text1.Location = New System.Drawing.Point(72, 40)
今回の例でのプロパティのうち、Font,TabIndex,ToolTipTextは変換していません。理由ですが、FontプロパティとTabIndexプロパティはデフォルトの値を利用する想定なのであえて入れていません。ToolTipTextは対応するプロパティがないため、対応を保留にしています。この辺については、コントロールを独自に拡張してプロパティを追加するか、今回の変換ツールで対応するか検討する必要があります。今回は説明を割愛しますが、最終的にはコントロールを独自に拡張してカスタムコントロールにした方が、移行しやすいような気がします。
VB6でのHeight,WidthプロパティはSizeプロパティ、Top,LeftプロパティはLocationプロパティが相当しますので、こちらに変換します。ただし、単位がTwipとPixelとで異なるので便宜的に15で割ってPixelの値を求めています。
メニューに関する変換
VB.Menu
Pictureプロパティ
個人的に一番課題と思ったのがPictureプロパティです。一部を抜粋して例示しますと、以下の様に、frxファイルのファイル名とデータのあるオフセットが書かれています。
Begin VB.CommandButton button1
Caption = "ボタン1"
Picture = "form1.frx":3C1A
このPictureプロパティで使用している画像データが別途用意があればよいのですが、そういったものがない場合、あるいは、元のソースがたくさんあるような場合はfrxファイルから抽出できた方が便利です。幸いオフセットがわかるので、その情報を基に抽出することが出来ます。
オフセットから先のデータ取得についてですが、バイナリファイルなので多少コツが必要になります。
事前情報としてオフセット位置からヘッダー情報があり、その後に実際の画像データがあるという知識が必要になります。 ヘッダーの構造ですが、順に以下の様になっています。
- ヘッダーのタイプの識別子 4バイト
- ヘッダーのサイズ 4バイト
- 画像のサイズ 4バイト
私の場合は、多少試行錯誤したのですが、思い通りに画像を抽出することが出来ました。抽出したファイルは一旦Tempフォルダに出力して、ソース上から参照するようにしています。
Me.button1 = New System.Windows.Forms.Button()
Me.button1.Name = "button1"
Me.button1.Image = Image.FromFile("C:\temp\form1.frx\012.gif")
まとめ
すべてをうまく変換できるかというとそういう訳にはいかないのですが、独自に変換ツールを作成することで、サードパーティ製のコントロールへの対応が容易になったり、後から、変換ルールが変わった場合にも変換ツールを修正することで対応可能になります。個別のソースをいちいち修正しなくても済むようになることが大きいです。
これを読んでいただいた方の少しでも参考になれば幸いです。