既存資産の.NET対応&移行方法
~ Technical Seminar for Developer ~
マクロソフト株式会社
テクニカルソリューション推進統括本部 SE部
プリンシパル SE
ジニゕス平井
Masato Genius Hirai
はじめに
~ ウォーミング・ゕップ ~
.NETの仕組み
~ 実行エンジンと強力なラブラリ群 ~
.NETゕプリケーションを駆動させるランタムエンジン
多くの開発言語をサポート
セキュリテゖシステムを搭載
堅牢な実行環境の提供
実行時コンパル
バージョン管理機能
オブジェクト指向
MS
VB
MS
C#
MS
J#
富士通
COBOL
Sun
Java
VB
コンパラ
C#
コンパラ
J#
コンパラ
Cobol
コンパラ
Java
コンパラ
中間言語 (MSIL)
バトコード
共通言語ランラム (CLR)
JavaVM
OS/ハードウェゕ
.NETゕプリを動作させるメカニズム
~ 実行時コンパルと厳格なセキュリテゖチェックがミソ ~
ソースコード
コンパラ
コンパラ
ゕセンブリ
EXE/DLL
コンパラ
(IL+MetaData)
署名検証審査
共通言語ランタム
コンパル済み
ゕセンブリ
クラスローダー
ジャストンタム
コンパラ
実行
コードゕクセス
セキュリテゖ審査
ネテゖブコード
中間コード
~ Microsoft Intermediate Language (MSIL) ~
ハードウェゕ(CPU)に依存しない命令セット
//C# Source Code
int x = 11;
int y = 22;
int z;
z = x + y
Source
コンパル C#→MSIL
// Code size 11 (0xb)
.maxstack 2
.locals init ([0] int32 x,
[1] int32 y,
[2] int32 z)
IL_0000: ldc.i4.s 11
IL_0002: stloc.0
IL_0003: ldc.i4.s 22
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: add.ovf
MSIL
IL_0009: stloc.2
'VB
Dim
Dim
Dim
z =
Source Code
x As Integer = 11
y As Integer = 22
z As Integer
Source
x + y
コンパル VB→MSIL
コンパル
MSIL→native
00000000
00000001
00000003
00000006
00000007
00000008
00000009
0000000c
0000000f
00000011
00000013
00000015
0000001a
0000001f
00000021
00000023
00000025
00000027
push
mov
sub
push
push
push
mov
mov
xor
xor
xor
mov
mov
mov
add
jno
xor
call
ebp
ebp,esp
esp,14h
edi
esi
ebx
dword ptr [ebp-4],ecx
dword ptr [ebp-8],edx
esi,esi
edi,edi
ebx,ebx
esi,0Bh
edi,16h
eax,esi
eax,edi
0000002C
ecx,ecx
Native
75FB8597
ガベージコレクション
~ Noメモリリーク、Noリソースリーク ~
ガベージ コレクション
マネージヒープの不要メモリをコンパクションする機構
世代(ジェネレーション)管理でパフォーマンスを向上
G0, G1, G2 の3世代
G0コンパクション → G1コンパクション → G2コンパクション
「新しいオブジェクト(G0)はすぐに消滅し、古いオブジェクト(G2
)は今後も利用させる可能性が高い」という統計のもとに実行
チューニングのためにパフォーマンス カウンタを提供
NextPtr
0
0
0
0
0
Object E
Object D
Object C
Object B
Object A
0
0
0
0
0
NextPtr
Object F
Object E
Object D
Object C
Object B
Object A
GC
0
1
1
1
Object F
Object E
Object D
Object B
GC
NextPtr
0
Object D
1
2
2
Object F
Object E
Object B
.NET バージョンマトリクス
~ VS2003 と 1.1 ベースはそろそろ注意 ~
1.0
ランタム
バージョン
トピック
対象 OS
VS 2002
1.0.3705
ADO.NET
ASP.NET
WinForm
98 / Me / NT
2000,
XP
1.1
1.1.4322
2.0
3.0
2.0.50727
832
SP1でバージョンゕップ →
3.5
2.0.50727
1433
ASP.NET 1.1
ADO.NET 2.0
ASP.NET 2.0
C# 2.0
VB 8.0
WPF
WF
WCF
CardSpace
ASP.NET AJAX
LINQ
C# 3.0
VB 9.0
98 / Me / NT
2000
XP / 2003
Vista
2000 sp3
XP sp2
2003
Vista
2008
XP sp2
2003 sp1
Vista
2008
XP sp2
2003 sp1
Vista
2008
◎
VS 2003
◎
VS 2005
◎
△
VS 2008
○
○
◎
2011/01/12
2012/04/10
2013/04/09
サポート期限
2007/07/10
2008/10/14
Vista 上での開発ツールのサポート
~ VB6 だけがある意味、特別です ~
実行環境
VB6ランタム
.NET Framework 1.0
.NET Framework 1.1
.NET Framework 2.0
.NET Framework 3.0
.NET Framework 3.5
Yes
No
Yes
Yes
Yes
Yes
←
←
←
←
←
Visual Studio .NET 2002
Visual Studio .NET 2003
Visual Studio 2005
Windows Vista に標準搭載
Visual Studio 2008
開発環境
Visual Basic 6
Visual Studio 6
Visual C++ 6.0
Visual Studio .NET 2002
Visual Studio .NET 2003
Visual Studio 2005
Visual Studio 2005 + SP1
VS2005SP1+Update Patch
Visual Studio 2008
Yes
No
No
No
No ← 作成したゕプリはOK
No ← 作成したゕプリはOK
No ← 作成したゕプリはOK
Yes
Yes
Vista での VB 6.0 のサポート
~ 延長されましたが早めに.NETに移行しましょう ~
Visual Basic 6.0 開発環境(IDE)& 実行環境
サポートは 2008年4月8日 まで
Visual Basic 6.0 はいまだ重要な位置づけを持っており、さらに
移行が比較的困難であるためサポートすることを決定
Windows Vista に Visual Basic 6.0 のランタムを同梱
サードパーテゖ製コンポーネント (ActiveXなど)
サポートは提供できません。製造元に問い合わせて下さい
ポント
マクロソフトが VB6 およびランタムについてWindows Vista
上で動作することを検証するというレベル
修正パッチやSPが提供される可能性は非常に低い
お客様のゕプリケーションが変更なしに Windows Vistaで動作す
ることを保証するものではありません
参照
http://www.microsoft.com/japan/msdn/vbasic/support/vistasupport.aspx
.NETを採用する必要性 ①
~ .NETに対応することで何が変わるのか? ~
非常に堅牢な実行環境
障害を隔離する機能を搭載
メモリリーク、ゕクセスバオレーションを防止
「落ちない・減らない・固まらない」を実現
完璧なセキュリテゖ
.NETのランタムがセキュリテゖを厳密に審査
ンターネット環境も意識したセキュリテゖ機構
驚異的なパフォーマンス
Windows / Web もかつ大規模分散ゕプリケーションも向上
再ビルドすることなく 64ビットに対応
徹底したバージョンニング
DLL 地獄に陥ることはない
一度動けば半永久的に動作する
.NETを採用する必要性 ②
~ .NETに対応することで何が変わるのか? ~
究極の開発生産性
開発言語の違いによる不可能がなくなり、難易度も同じ
コンシューマからエンタープラズまでのすべてに一貫した
プログラミング モデルを提供
多種多様のデバスに対応
配置・配布・保守コストの大幅削減
レジストリを使わないため配置やバックゕップがシンプル
仕様変更、機能追加に対しての俊敏性がある
これまでの資産を有効活用
COMやDLLラブラリなど現行資産もフルに活躍
Webサービスなら非 Windowsシステムとの接続も容易
最新テクノロジーの積極的な採用
XML、SOAP、UDDI、WS-*、AJAX、XHTML などを実装
.NET Framework 3.0
~ .NET は第3世代を迎えた ~
Microsoft .NET Framework 3.0
Windows
Presentation
Foundation
Windows
Foundation
Windows
Workflow
Foundation
Windows
CardSpace™
UXの強化
分散ゕプリ構築
多様な形態
IDメタシステム
生産性向上
相互運用の実現
生産性と柔軟性
セキュゕで便利
形態の汎用性
サービス指向
拡張性
標準プロトコル
Communication
相互運用の実現
.NET Framework 2.0
.NET Developer Stack
~ 最新・最強のラブラリ ~
ASP.NET
AJAX
ASP.NET
3.5
ASP.NET
2.0
LINQ
Windows
Forms
2.0
ADO.NET
2.0
WPF
3.5
WCF
3.5
WF
3.5
WPF
3.0
WCF
3.0
WF
3.0
Card
Space
3.5
Card
Space
3.0
Base Class Library 2.0 / 3.5
Common Language Runtime 2.0
CLR
Windows Vista, Windows XP, Windows Server 2003 / 2008
.NET はすべてをカバー
~ 統合開発ツール Visual Studio とともに発展 ~
Windows
ゕプリケーション
Web
ゕプリケーション
WPF
ゕプリケーション
Workflow
ゕプリケーション
スマートデバス
ゕプリケーション
WCF サービス
Windows
サービス
Sliverlight
ゕプリケーション
Office
ゕプリケーション
.NET ラブラリ
開発言語の選定
~ .NETになってもVBで大丈夫か? ~
.NETでは多数のプログラミング言語が利用できます。また、各言語か
ら.NET Frameworkの機能やクラスラブラリに平等にゕクセスできます。
このためプログラミング言語の違いによる機能差やパフォーマンスの差
はほとんど生じません。また、「C++のクラスをC#で継承してVBで使う」
といったような多言語とのシームレスな連携をサポートしています。
ほとんどの開発者は自分がもっとも得意とする「第1言語」を持ってい
ます。そのスキルやこれまでの資産を最大限に活用して高い生産性を維持
することが可能です。
VBは世界最大のユーザー数を誇る開発言語です。今後もご安心して利用
できます。
開発言語の選択
~ C#とVB.NETのどちらを選ぶか?それとも ~
Visual Basic
VBA
ASP
移行
Visual Basic
乗換
Amateur
新規
乗換
Visual J++
Java
ASP
乗換
移行
Visual C++
C/C++
継続
Visual C#
Visual C++
(マネージC++)
Visual C++
(Win32)
Visual Basic
~ 圧倒的なユーザー数! もうVBに不可能はない ~
オブジェクト指向プログラミングを完全サポート
継承 / ポリモーフゖズム / オーバーロード
構造化例外処理
大量のOn Error 文から開放され保守性が向上
Try…Catch… Finally…
フリースレッデゖング
安全なマルチスレッド・ゕプリケーションの作成が容易
.NET クラスラブラリにフルゕクセス
新しいプロジェクトタプ
Windows サービス
コンソール ゕプリケーション
: サービス ゕプリケーション
: コンソール ゕプリケーション
ゕップグレード・ウゖザード
VB6のコードを.NET用にコンバート
ソースレベルでの変換率は約90%。無修正での稼動率が約40%
Visual C#
~ 徹底したオブジェクト指向 .NET時代の開発言語 ~
ベースはC++
C++は難しい / 不要な機能が多すぎる / 開発者の手腕に依存
ANSI準拠のC++はそのまま
.NET Framework Class Library の多くは C# で記述されている
オブジェクト指向プログラミング言語
Javaプログラマも容易に使用 (Javaよりも多少複雑)
今後、主流になる開発言語
特徴
タプセーフ/オーバーフローチェック/配列の範囲チェック
ポンタレス
ただし、unsafeモードでの利用は可能
#include, マクロなど C++のコンストラクタを排除
ECMA スタンダード
.NETスタンダードな言語として位置付け
VB か C# か?
~ 機能的およびパフォーマンスの差はない ~
.NETでは何が最適な開発言語か?
好きな言語を使って下さい
パフォーマンスはほとんど変わらない
どの言語からも .NETの機能がすべて利用できる
VB開発者がC#を取得できるのか?
C や Javaの経験がなければかなり難しい
VB6 から .NETへの移行は多少なりともエンジニゕの再教育が必要
どうせやるならオブジェクト指向が徹底されているC#がいい?
オブジェクト指向の開発は、今後ますます重要になる
VBより C のほうが優れているという悪しきメージ
C# が.NETスタンダード言語であることは事実
どうせやるならオブジェクト指向が徹底されているC#がい
「VB6 開発者は VB.NETへ移行すること」が
もっとも低コストで低リクスである
.NETが提供する相互運用サービス
~ Win32と.NETマネージドコードの相互運用 ~
.NET Frameworkでは、マネージドコードからWindows APIや
COM, ActiveXコントロールを利用するための相互運用サービスが
提供されています。すべてのコードを.NET Frameworkに移行する
ことが最善の策ではありますが、大規模なプロジェクトやシステム
では一度にすべてを.NETに移行させることは困難です。このた
め、.NETとWin32(COM, Win32 API,..)のハブリッド的なソ
リューションも有効な手段であり、既存の資産を有効に活用しつつ
段階的に.NET移行していくことが容易なのです。
プラットフォーム呼び出し
~ PInvoke : Platform Invocation Services ~
Win32 APIや C DLLの関数を呼び出す機構
マーシャリング機能(Managed Heap ←→Unmanaged Heap)
エントリポント指定
System.Runtime.InteropServicesクラス
Unmanaged DLL
Windows API
.NET
Managed
Code
[DllImport("shell32.dll",
EntryPoint="SHGetSpecialFolderPathW")]
public static extern bool SHGetSpecialFolderPath(
int Owner,
[MarshalAs(UnmanagedType.LPWStr)] string Path,
int Folder,
int Created
);
Private Declare Ansi Function SHGetSpecialFolderPath
Lib "shell32.dll" Alias "SHGetSpecialFolderPathA" (
ByVal Owner As Integer, _
ByVal Path As String, _
ByVal Folder As Integer, _
ByVal Create As Integer _
) As Boolean
COM相互運用機能
~ RCW : Runtime Callable Wrapper ~
.NETマネージコードからCOMを呼び出す機構
<InterOp>.DLL
.NET→COM のプロキシの役割を担う”ラッパーDLL"
COMを参照設定することで自動生成
タプ ラブラリ ンポータ (tlbimp.exe)で手動生成も可能
マーシャリング、参照カウント、ラフタムを管理
SuperCalc.Calculator obj = new SuperCalc.Calculator();
//C#
Dim obj As New SuperCalc.Calculator()
'VB
.NET
Managed Code
(クラゕント)
Runtime
Callable
Wrapper
IUnknown
IFoo
COM
COM+
COM相互運用機能
~ CCW : COM Callable Wrapper ~
COM(Win32ゕプリ)から .NET を呼び出す機構
.NETのクラスラブラリ(DLL)をCOM/COM+のように見せる
TlbExp.exe でタプラブラリを生成
RegAsm でレジストリに登録
GACUtil /i: でGACに登録、またはゕプリケーションフォルダに配置
VS.NETでは[COM相互運用機能の登録]にチェック
C:¥> TlbExp "MydotNetforCOM.dll"
C:¥> RegAsm "MydotNetforCOM.dll"
C:¥> GACUtil /I: "MydotNetforCOM.dll"
.NET
IFoo
Managed Code
(クラスラブラリ)
COM
Callable
Wrapper
IUnknown
IDispatch
Win32
Client
IFoo
コンポーネントの移行
~ DLLは段階的に移行可能 ~
Win32 DLL, COM DLLのまま
COM DLL : RCW 参照設定
Win32 DLL : P/Invoke
Win32アプリ
COM互換の.NETクラスラブラリを作成
.NETからも利用
Win32ゕプリからも利用
純粋な .NETクラスラブラリを作成
.NETからの利用に限定
Webサービスを作成する
Win32ゕプリは Web Service Toolkitに
より利用可能
.NETゕプリからはネテゖブに利用可能
他のシステム(JAVA,…)でも利用可能
.NETアプリ
実行時バンデゖング
~ .NETではリフレクションを利用! ~
COM : Late Binding
VB だけの固有機能(互換性のため)
Dim o As Object
Set o = CreateObject("Project1.Class1") 'インスタンス化
o.WhoAreYou = "Masato Hirai"
'プロパティ
Text1.Text = o.SayHello()
'メソッド呼び出し
.NET : Reflection
Imports System.Reflection
Dim asm As [Assembly] = [Assembly].LoadFrom("Project1.dll")
'インスタンス化
Dim o As Object = asm.CreateInstance("Project1.Class1")
'プロパティ
o.GetType().InvokeMember("set_WhoAreYou", BindingFlags.InvokeMethod, _
Nothing, o, New Object() {"Masato Hirai"})
'メソッド呼び出し
TextBox1.Text = CType(o.GetType().InvokeMember("SayHello", _
BindingFlags.InvokeMethod, Nothing, o, Nothing), System.String)
Windowsメッセージの処理
~ Windowsメッセージを直接処理することの是非 ~
.NETクラスラブラリで制御できないものに限る
メッセージは可能な限り、System.Windows.Forms.Message
クラスを利用してハンドルは、IntPtr型を利用する
Const WM_NCLBUTTONDOWN As Long = &HA1
Const HTCAPTION As Long = 2
Dim msg As Integer = WM_NCLBUTTONDOWN
Dim wParam As New IntPtr(HTCAPTION)
Dim lParam As New IntPtr(0)
Dim myMessage As System.Windows.Forms.Message
'Windowメッセージの作成
myMessage = System.Windows.Forms.Message.Create( _
Me.Handle, _
msg, _
wParam, _
lParam)
'マウスのキャプチャーを解放(=ReleaseCapure関数)
Capture = False
'自分のウィンドウプロシージャへ渡す(=SendMessage関数)
WndProc(myMessage)
VB6からVB.NETへの移行
~ 簡単か難しいか? 作り直した方がいいのか? ~
VB6 から VB.NETへ移行は、他の言語よりも比較的容易だと言
えます。VS.NETに付属している「ゕップグレード ウゖザード」を
使えば機械的にソースコードを変換してくれます。しかし、その精
度とクオリテゖは完璧でないため、多少の修正作業が必要となりま
す。「ゕップグレード ウゖザード」を使っても一部のActiveXコン
トロールや描画関連コードなどゕップグレードできない部分も多く
あります。
.NETでは生産性が飛躍的に向上しています。結局、再設計およ
びスクラッチから作り直した方がよい場合がほとんどです。
ゕップグレード対策
~ ほとんどは機械的に可能だが手直しが必要 ~
Code Advisor for Visual Basic 6.0
VB6のコードを分析して、.NETへ移行する際の改善点を提案する
Visual Basic 6.0用のゕドンツール
Visual Basic ゕップグレードウゖザード」
VB6のプロジェクト(*.vbp)のソースコードを.NET用に機械的
にコンバートするツール(VS.NETにバンドルされている)
機械的に移行できないもの
DAOとRDOのデータバンデゖング(コードはOK)
グラフゖックス関連(Line, Circle, Print, …)
印刷関連(Printerオブジェクト)
Drag & Drop操作のコード
Visual Basic 6 コードのゕップグレード
コードエデゖタ上で VB6のコードを入力して.NET用のコードに変
換してくるゕドン
問題点リスト
~ VB6からの移行で何が問題になるか? ~
致命度
★★★★★
致命度
★★
致命度
★★
致命度
★★★★
致命度
★★★
致命度
★★★
致命度
★★★★
致命度
★★
致命度
★
致命度
★★
Printerオブジェクトは移行できない (印刷関連は壊滅)
グラフゖックス命令 (Line, Print, PSet,..)は全滅
DataコントロールとRDCは移行できない (コードはOK)
ADOコードはADO.NETでなくADOまま
ADODCデータバンデゖングは互換ラブラリで対応
ActiveXコントロールは .NETコントロールに置換しない
ActiveX コントロール(OCX)プロジェクトは移行できない
コントロール配列は互換ラブラリで辛うじて対応
データ型の改修
(Variant→Object, Currency→Decimal, …)
デフォルトプロパテゖが解決されない
言語仕様変更リスト
~ 細部にわたり注意が必要~
致命度
★★★★★
致命度
★★★★
致命度
★★★★
致命度
★★★
致命度
★★★★
致命度
★★★
致命度
★
致命度
★
致命度
★
致命度
★
0 ベースの配列 (Dim arr(1 To 10) As Integerは不可)
固定長文字列変数の機構が変更 (Dim s As String * 10)
xxxB関数(LenB, MidB, LeftB, RightB,…)は未サポート
変数のスコープがブロック単位 (For Each )
AutoRedrawは使えない (Paintベントへの移動)
引数は ByVal がデフォルト
構造化例外処理 (Try..Catch.. Finally, Throw)
直接メモリへのゕクセス禁止 (VarPtr, StrPtr, ObjPtr)
ショートサーキット論理演算子 (AndAlso, OrElse)の新設
複合代入演算子(+=)、ビットシフト演算子(>>)の新設
移行手順
~ どこまでコードを洗練させるか? 適度の妥協も必要? ~
ゕップグレードウゖザードによる機械的コンバート
レポートを参考にコードを修正
とりあえずコンパルエラーが無くなるまでがんばる!
印刷、グラフゖックス、Drag&Dropなどの移行不能コードを改修
Option Explicit On / Option Strict On
未宣言変数を除去して型変換を強要させ、タプセーフなコードへ
VB6固有の関数を撤廃
参照設定から"Microsoft.VisualBasic.Compatibility"を外す
.NET Frameworkのクラスラブラリの関数を採用
Windows APIを撤去
ActiveXコントロールを .NETコントロールへ置換
コードの精査
新機能への切り替え
コントロール配列
~ "コントロール配列"はなくなったが、心配御無用! ~
「ゕップグレード ウゖザード」ではVB6互換ラブラリ
の"コントロールArray"クラスとしてコンバートされる
VB 6と同じコーデゖングが可能だが、無理やり互換性を保つ構造
静的なコントロール配列の実装方法
ベントプロシージャの Handles 句に対象のベントを列挙
Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter
CType(sender, TextBox).BackColor = Color.Yellow
End Sub
動的なコントロール配列の実装方法
AddHandler / RemoveHandler でベントプロシージャを脱着
AddHandler TextBox1.Enter, AddressOf TextBox_Enter
AddHandler TextBox2.Enter, AddressOf TextBox_Enter
Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As …)
固定長文字列
~ .NETには固定長文字列というデータ型はない ~
VB6互換ラブラリに代替クラスがある
参照 : Microsoft VisualBasic.NET Compatibility Runtime
実体 : Microsoft.VisualBasic.Compatibility.dll
ンポート : Microsoft.VisualBasic.Compatibility.VB6
FixedLengthStringクラス
VB6からの移行用なので可能な限り使わないほうがよい
String型のもつメソッドがすべて利用できなくなる
Valueプロパテゖによるゕクセス
'// VB6
Dim s As String * 3
s = "ABCDEF"
Debug.Print s 'ABC
s = "あいうえお"
Debug.Print s
'あいう
'// VB.NET
Imports Microsoft.VisualBasic.Compatibility.VB6
Dim s As New FixedLengthString(3)
s.Value = "ABCDE"
Console.WriteLine(s.Value) 'ABC
s.Value = "あいうえお"
Console.WriteLine(s.Value) 'あいう
コントロール
~ 3つのパターンがある ~
UserControl クラスを継承して作成
[Windows コントロール ラブラリ] テンプレート
複合コントロールの作成が容易
ユーザー登録用コントロール、性別選択用コントロール、...
Public Class UserEntryCtrl
Inherits System.Windows.Forms.UserControl
既存のコントロールを継承して作成
数値入力用のテキストボックスやオーナードロー・リストボックス
など...
Public Class NumTextBox
Inherits System.Windows.Forms.TextBox
Control クラスを継承して作成
柔軟性はあるが描画を含むすべてコードを実装する必要がある
Public Class MyGrid
Inherits System.Windows.Forms.Control
ASPからASP.NETへの移行
~ 移行作業は大変だが効果は絶大 ~
ASPからASP.NETへの移行は、ほとんど書き直す作業が伴います。
HTML部分はそのまま流用できますがVBScriptまたはJScriptのサー
バーサドのコードに関しては、大幅な修正を余儀なくされます。
ASPとASP.NETは同一のWebサーバー(IIS)で共存して稼動す
ることができるため段階的に移行していくことも可能です。また、
Windowsゕプリケーションと同じコード、同じ手順、同じデバッ
グ手法なので今まで VB6などWindowsゕプリケーションを開発し
ていたエンジニゕでも容易にWEBゕプリケーションを構築できま
す。
ASP.NET : 開発言語
~ 1ページ内では単一言語 ~
ASP
プログラミング言語として選択肢は"VBScript"か"JScript"のみ
同じページに複数言語によるスクリプトのブロックの混在が可能
<script language="vbscript" runat="server">
Response.Write "Hello VBScript."
</script>
<script language="jscript" runat="server">
Response.Write("Hello JScript.");
</script>
ASP.NET
同じページで複数言語によるスクリプトのブロックの混在は不可
VS.NETの場合はプロジェクト単位に開発言語を選択
<%@ Page Language="vb" Inherits="WebApplication1.WebForm1" %>
<%
Response.Write("Hello VB.NET.")
%>
構造の変更
~ 2つの大きな変更点 ~
<SCRIPT>ブロック内ですべてを宣言
NG
<%
<% RenderMe("Hello") %>
RenderMe("Hello")
Sub RenderMe(msg)
Response.Write(msg)
End SUB
%>
<script language="vb" runat=server>
Sub RenderMe(ByVal msg As String)
Response.Write(msg)
End SUB
</script>
表示機能の無効化
Response.Writeメソッドで文字列を出力するように修正
NG
<%Sub RenderMe(msg)%>
<H1><%= msg %></H1>
<%End SUB%>
OK
<script language="vb" runat=server>
Sub RenderMe(ByVal msg As String)
Response.Write("<H1>" & msg & "</H1>")
End SUB
</script>
API の変更
~ Request APIの変更 ~
Request(item)
Request.QueryString(item)
Rewuest.Form(item)
ASP : http://localhost/demo/test.asp?values=123&values=456
1ベースの配列
<%
Response.Write Request("values")
Response.Write Request.QueryString("values")(1)
%>
'123,456
'123
ASP.NET :
http://localhost/demo/test.aspx?values=123&values=456
0ベースの配列
<%
Response.Write(Request("values"))
'123,456
Response.Write(Request.QueryString.GetValues("values")(1)) '456
%>
VB言語仕様の変更
~ VBの言語仕様変更に伴う影響はASP.NETにも! ~
Option Explicit が既定(変数宣言が必須)
よくあるエラー
Set, Let文
カッコなしの呼び出し
デフォルト ByVal
→省略しなければならない
→括弧をつける
→ByVal, ByRefを明示的につける
Set cn = Server.CreateObject("ADODB.Connection")
cn = Server.CreateObject("ADODB.Connection")
MySubProc "Hello World." '←NG
MySubProc("Hello World.") '←OK
デフォルトプロパテゖの変更
Do Until rs.EOF
Response.Write(rs(0))
Response.Write(rs(0).Value)
rs.MoveNext()
Loop
'←NG
'←OK
'←NG
'←OK
ステート管理
~ Session, Applicationオブジェクトは共有できない ~
ASPとASP.NET間で共有できない
一貫したセッション管理下ではASPかASP.NETのどちらかに統一
ASP.NETのステート管理
web.configフゔルの<sessionState>セクションで設定
"InProc", "StateServer", "SqlServer", "Off" の4種類
COMコンポーネントの参照をセッション変数に格納する場合は
"InProc"(デフォルト)のみ有効
<!-- セッション状態の設定 -->
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
COM関連
~ ASP.NETからCOMをコールする場合 ~
スレッドモデルの変更
ASP.NETは"MTA"(マルチスレッドゕパートメントモデル)
VB6で作成したCOMやADOなどは"STA"(シングルスレッドゕ
パートメントモデル)
aspCompat="True"
<%@ Page aspCompat="True" %>
ASP.NETを"STA"モードで実行させるオプション
パフォーマンスが若干低下するため必要時のみ
Early Binding(事前バンド)への変更
Late Binding(実行時バンデゖング)でも動作する
Dim rs1 As New ADODB.Recordset
'// 事前バインディング
rs1.Fields.Append("F1", ADODB.DataTypeEnum.adVarChar, 10)
Dim rs2 As Object
'// 実行時バインディング
rs2 = Server.CreateObject("ADODB.Recordset")
rs2.Fields.Append("F1", ADODB.DataTypeEnum.adVarChar, 10)
移行手順
~ はじめは小さいページから挑戦しよう! ~
Visual Studio [既存項目の追加]で ASPフゔルを追加
拡張子を変更
".asp" → ".aspx"
<%@ Page %>デゖレクテゖブをHTMLの冒頭に追加
Language = "vb"
Codebehind = "demo.aspx.vb"
Inherits = "MyApps.WebForm1"
プロジェクトをコンパル
タスクリストの指示に従って問題を逐次修正
スクリプトブロックの構造上の問題を解消
変数のデータ型を宣言
事前バンデゖングへの切り替え
ラウンドトリップ型への改造
ASP.NETのWebコントロールへの切り替え
『1から作り直した方が良い場合が多い』
ADOからADO.NETへの移行
~ そのまま使うか? ADO.NETに書き直すか? ~
ADO.NET はADOの利点を引き継ぐとともにADOの欠点と指摘されてい
た階層間データ転送の仕組みを改善し、データソースとの関係を明確に分
離した非接続モデルを採用しました。ADO.NETは、ADOと「似て非なる
もの」ですが、ンターネットおよびn階層ゕプリケーションの構築に必
要な要件がすべて備わっています。
ADOのコードは、COM互換機能により.NETマネージドコードからもそ
のまま利用できますが、ADO.NETのパフォーマンスとスケーラビリテゖ
は特筆すべきものがあります。移行作業の中でADO.NETへの書き直しは、
もっとも効果が大きい部分なのです。当然ながら、ADO.NETのメリット
を最大限に活用するには、データゕクセスの設計を見直す必要もあります。
データゕクセス・テクノロジーの進化
~ 時代とともにニーズは変わる ~
DAO
RDO
ADO.NET
ADO
Data Provider
RDS
OleDb
Sql
Oracle
ODBC
OLE DB
Jet Engine
DASQL
Jolt
SQL ORA
…
ODBC
Jet
Access
Excel SQL ORA …
Excel
SQL Server
Oracle
XML
新しいデータゕクセスの必要性
~ またしても新しいデータゕクセス・テクノロジー ~
ADOの問題点と課題
すべての階層でCOM/DCOMが利用できる環境とは限らない
他のプラットフォームを含む分散環境でデータ伝送の手段がない
ンターネット上でRecordsetをやり取りすることは困難
リソース集約型でスケーラビリテゖに欠ける
Presentation Tier
COMのマーシャリング コストが高い
Windows Apps
XMLのサポートが不完全
データソースに依存したプログラミング
Business Tier
Data Store
Data Tier
COM
DCOM
ADO
Recordset
ADO
Recordset
DCOM
DCOM
Presentation
Tier Web Apps
IIS
ASP
HTTP
ADO.NETの概要
~ ADO.NETのポントはここだ ~
ンターネットを意識した非接続型モデル
階層間でデータ転送が容易
異なるゕプリケーション/システム間でXMLによるデータ交換
パフォーマンスとスケーラビリテゖを大幅に向上
XMLをネテゖブにサポート
XMLからの読み込みとXMLへの書き出しをサポート
DOM, XSD, XSLTなどのXML機能を統合
DataSet クラスの新設
リレーショナルデータベースのローカルコピー
XMLによる永続化と復元が可能
複数テーブルを格納でき、そのリレーションシップや制約も管理
データプロバダとデータセットの分離
実際のデータソースへのゕクセスはデータプロバダが担当
データソースに依存しないデータ操作はデータセットが担当
ADO.NETのゕドバンテージ
~ ADO.NETにすると何が良くなる? ~
相互運用性
XMLでのデータ表現
システム間・階層間をXMLでデータ転送
スケーラビリテゖ
非接続型モデルを改善
更新メカニズムの刷新
強い型付け
コードの信頼性
Presentation Tier
Windows Apps
Business Tier
HTTP
TCP/IP
HTTP
TCP/IP
Data Store
Data Tier
DataSet
Presentation
Tier
DataSet
IIS
ASP.NET
HTTP
ADO.NETのオブジェクトモデル
~ データソースに依存する部分をデータプロバダに封じ込めた ~
データプロバイダ
DataAdapter
DataReader
DataRelation
SELECT
UPDATE
Command
Parameter
Connection
データセット
INSERT
DataRow
DELETE
DataColumn
Transaction
DATA STORE
DataTable
DataView
XML / XSD
ADOとADO.NETの比較
~ 違いは結果セットの表現が COMバナリか標準XMLか ~
ADO
ADO.NET
ゕーキテクチャ
COM コンポーネント
.NET ベースクラス
モデル
常時接続モデル
クラゕント / サーバー
非接続モデル
ンターネット / 分散環境
スケーラビリテゖ
低い
高い
階層間のデータ転送
COMバナリ
XML
データ転送プロトコル
COM / DCOM
TCP/IP, HTTP
XMLサポート
あり(独自フォーマット)
あり(W3C標準)
XSD, XSLTサポート
なし
あり
カーソル
Server/Client カーソル
カーソルの概念なし
レコードの走査
MoveNext
MoveXXXX
DataReader: Readメソッド
DataSet: Rows コレクション
ンターネットで使用
△ RDS (IE限定)
○ HTTP/XML
データソースとの関連
密
疎
ADOとADO.NETの比較
~ カーソルという概念はもはやADO.NETにはない ~
ADO
ADO.NET
複数テーブルの管理
不可
可能(DataSet クラス)
結果セット管理
Recordset オブジェクト
DataTable オブジェクト
DataReader オブジェクト
(SqlResultSetオブジェクト)
リレーションシップ
(JOINクエリーで処理)
Relation オブジェクト
接続
Connection オブジェクト
xxxConnection オブジェクト
コマンド
Command オブジェクト
xxxCommand オブジェクト
パラメータ
Parameter オブジェクト
xxxParameter オブジェクト
行へのゕクセス
(カーソル)
EOF, BOF 判定
DataRow オブジェクト
コレクション ループ
列へのゕクセス
rs.Fields("Name")
rs.Fields(0)
Rows(0).Item("Name")
Rows(0).Item(0)
Customer(0).Name
トランザクション
cn.BeginTrans メソッド
xxTransaction オブジェクト
データ取得の比較
~ オブジェクトにとって微妙に違う ~
ADO – Recordset
カーソル操作(MoveNext)
EOF 判定
Fieldコレクション
Do Until rs.EOF
For n = 0 To rs.Fields.Count - 1
Response.Write(rs(n).Value)
Next
rs.MoveNext()
Loop
ADO.NET – DataReader
シーケンシャルなゕクセス
Readメソッド
While rd.Read()
For n = 0 To rd.FieldCount - 1
高速
Response.Write(rd(n).ToString())
軽量
Next
End While
シリゕラズ不可
ADO.NET – DataSet
コレクション操作
やや低速
シリゕラズ可能
Binary, SOAP-XML
For Each r In ds.Tables(0).Rows
For Each c In ds.Tables(0).Columns
Response.Write(r.Item(c).ToString())
Next
Next
DataAdapterクラス
(データプロバダ)
~ 結果セットの取得および更新を管理するクラス ~
ポント
データソースからデータセットにデータを充填(Fillメソッド)
SqlDataAdapter dap = new SqlDataAdapter("SELECT * FROM authors", cn);
DataSet ds = new DataSet("MyDs");
dap.Fill(ds,"authors");
データセットの変更をデータソースに反映(Updateメソッド)
CommandBiulderクラスにより更新コマンドの自動生成も可能
DataSet
DataAdapter
Fill
Select
UPD
INS
DEL
Update
Connection
SqlDataAdapter dap = new SqlDataAdapter("SELECT * FROM authors", cn);
DataSet ds = new DataSet("MyDs");
ds = (DataSet) this.dataGrid1.DataSource;
SqlCommandBuilder cb = new SqlCommandBuilder(dap);
dap.Update(ds, "authors");
DATA
STORE
データセットの更新
~ ンテリジェンスな更新メカニズム ~
第1段階 – DataSetに対しての更新(非接続)
変更前の
追加: NewRow → Rows.Add(row)
データを
修正: BeginEdit → 変更 → EndEdit
保持
削除: Rows(n).Delete()
現バージョン(Current)に対して追加・修正・削除
Original
元バージョン(Original)が作成される
WHERE句パラメータ用
Current
F1
F2
RowState
1
AAA
Unchanged
2
BBB
Unchanged
3
CCC
Unchanged
F1
F2
1
AAA
2
BBB
Current
修正
削除
追加
F1
F2
RowState
1
XXX
Modified
2
BBB
Deleted
3
CCC
Unchanged
4
ABC
Added
データソースの更新
~ 今までになかった考え方 ~
第2段階 – DataAdapterでデータソースに反映(要接続)
DataAdapter.UpdateメソッドにDataSetを渡す
DataAdapterの各更新Commandが実行される
現バージョンの値が SET 句パラメータにセット
Current 元バージョンの値がWHERE句パラメータにセット
F1
F2
RowState
1
XXX
Modified
2
BBB
Deleted
F1
F2
3
CCC
Unchanged
1
AAA
4
ABC
Added
2
BBB
Original
UPDATE MyTB SET F1 = @F1, F2 = @F2
WHERE (F1 = @Original_F1) AND (F2 = @Original_F2)
DATA STORE
DataAdapter
UPDATE
INSERT INTO MyTB (F1, F2) VALUES (@F1, @F2)
INSERT
DELETE FROM MyTB
WHERE (F1 = @Original_F1) AND (F2 = @Original_F2)
DELETE
バッチ更新のサンプル
~ いかにT-SQLを簡略化してデータ転送量を抑えるか! ~
Dim adp As New SqlDataAdapter("SELECT * FROM Sample1", cn)
adp.InsertCommand _
= New SqlCommand("INSERT INTO Sample1 (F2, F3) VALUES (@F2, @F3)")
adp.InsertCommand.Parameters.Add( _
New SqlParameter("@F2", SqlDbType.Int, 4, "F2"))
adp.InsertCommand.Parameters.Add( _
New SqlParameter("@F3", SqlDbType.VarChar, 10, "F3"))
adp.DeleteCommand = New SqlCommand("DELETE FROM Sample1 WHERE F1 = @F1")
adp.DeleteCommand.Parameters.Add( _
New SqlParameter("@F1", SqlDbType.Timestamp, 8, "F1"))
adp.UpdateCommand _
= New SqlCommand("UPDATE Sample1 SET F2=@F2, F3=@F3 WHERE F1=@F1")
adp.UpdateCommand.Parameters.Add( _
New SqlParameter("@F2", SqlDbType.Int, 4, "F2"))
adp.UpdateCommand.Parameters.Add( _
New SqlParameter("@F3", SqlDbType.VarChar, 10, "F3"))
adp.UpdateCommand.Parameters.Add( _
New SqlParameter("@F1", SqlDbType.Timestamp, 8, _
ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), _
"F1", DataRowVersion.Original, Nothing))
adp.UpdateBatchSize = 100
adp.Update(ds.Tables(0))
.NETでADOを使う
~ .NETマーネジコードからADOの利用も可能 ~
.NETでもADOは使える
短期的なソリューション
暫定的なステップ
.NET ラッパークラス(adodb)への
参照設定が必要
ADOコードからADO.NETコードへ
VBのUpgrade Wizardでは、ADOはADOのまま
ASP 内のスクリプトは手作業で移行
ADOのRecordsetをADO.NETのDataSetに変換可能
既存COMコンポーネントとの相互運用に便利
OleDbDataAdaper.Fill メソッド
OleDbDataAdapter1.Fill(ds.Tables[0], rs);
逆は DataSet → XMLフゔル → Recordset
ADO.NETでの排他ロック
~ 使うなと言われると余計に使いたくなる ~
BeginTransaction にIsolationLevel.Serializableで開始
RollBack, Commitメソッドで解除
CommandオブジェクトのTransactionプロパテゖにセット
※ 同時実行性が極度に低下してスケーラビリティに大きな影響を与えます
Dim cmd As New SqlClient.SqlCommand()
cmd.CommandText = "SELECT au_lname FROM Authors"
cmd.Connection = cn
Dim tx As SqlClient.SqlTransaction
tx = cn.BeginTransaction(IsolationLevel.Serializable)
Dim rs As SqlClient.SqlDataReader
cmd.Transaction = tx
rs = cmd.ExecuteReader(CommandBehavior.CloseConnection)
MessageBox.Show("この段階で更新ロックがかかっています!")
While rs.Read()
System.Diagnostics.Debug.WriteLine(rs.GetString(0))
End While
rs.Close()
MessageBox.Show("まだ更新ロックがかかっています!")
tx.Rollback()
データゕクセスの最適化
~ 生かすも殺すもプログラマの腕の次第 ~
DataAdapterによるバッチ更新
行を特定するWHERE句の条件を最小限に!
全カラム比較を避ける
UpdateBatchSizeプロパテゖの設定
規定は 1 なので一度に複数行を変更するにはサズを大きくする
更新用のDataSetを伝播させる場合は、変更行のみに圧縮
行を返さないクエリーは ExecuteNonQuery メソッド
更新された行数のみ返す
スカラー値の取得は ExecuteScalerメソッド
COUNT, SUM,..などでSELECTで単一値を取得する場合に高速
なるべくゕセンブリにT-SQLを埋め込まない
ストゕドプロシージャの利用
T-SQLで処理できることはT-SQLで記述すべし
移行手順
~ かなりの部分は書き直しなるが効果は絶大! ~
事前調査と検討事項
データバンデゖング コントロール
DAO, RDCデータコントロールの利用状況
.NETマネージドプロバダが提供されているか
常時接続でのRecordsetに対する更新処理があるか
ADO.NETではバッチ更新が原則
DataSetを利用するかDataReaderでフェッチするか
同時実行違反に対する対策
ADOのままにするかADO.NETに書き直すかを決定
暫定的な.NET対応であればADOのままでよい
コードの修正作業
部分的に出来ないので一気に修正作業を行う
パフォーマンスや動作検証をしっかり
テスト期間は長めにとる
参考資料
『ADO プログラマのための ADO.NET』
http://www.microsoft.com/japan/msdn/net/upgrade/adonetprogmsdn.asp
『Microsoft Win32 と Microsoft .NET Framework API』
http://www.microsoft.com/japan/msdn/net/general/win32map.asp
『Visual Basic 6.0 から Visual Basic .NET への移行』
http://www.microsoft.com/japan/msdn/vbasic/techinfo/upgrade/transition/default.asp
『Visual Basic .NET ゕップグレード ガド』
http://www.microsoft.com/japan/msdn/vbasic/techinfo/upgrade/guide.asp
『ASP から ASP.NET への変換』
http://www.microsoft.com/japan/msdn/net/upgrade/convertasptoaspnet.asp
『ASP.NET に移行する際の主な検討事項』
http://www.microsoft.com/japan/msdn/net/aspnet/aspnetmigrissues.asp
『Visual Basic 6.0 と .NET のコントロールの相違点』
http://www.microsoft.com/japan/msdn/net/upgrade/actxvnetcontrols.asp
参考資料
『Visual Studio Tools for the Microsoft Office System の紹介』
http://www.microsoft.com/japan/msdn/vstudio/office/productinfo/features/officetools.asp
『Visual Basic .NET におけるオブジェクト指向プログラミング』
http://www.microsoft.com/japan/msdn/vbasic/techinfo/upgrade/programming.asp
ダウンロード
『Code Advisor for Visual Basic 6.0 - 日本語版』
http://www.microsoft.com/japan/msdn/vbasic/downloads/codeadvisor/default.asp
まとめ
Win32ゕプリケーションを.NET Frameworkに対応さ
せるための移行作業は簡単なのでしょうか?
答えは"NO"です。.NETへの移行は実際それほど単純で
ありません。VB6に関しては「ゕップグレード ウゖザー
ド」を使って機械的にソースコードを変換することがで
きますが、100%完璧ではありません。
移行作業をスムーズに行うためには、現行資産を慌てて
ゕップグレードする前に先にエンジニゕの方々を.NETへ
シフトしておかなければなりません。移行作業にはどう
しても.NETを熟知したエース級のエンジニゕが必要とな
ります。
いづれにしても.NETのハードルは高いですが予想以上
の効果が期待できますので、早めにご対応下さい。
Questions and Answers !
これは?
あれは?
ウゲェ~
なんで?
Thanks for Attending !
ゕンケートにご協力ください。
© Copyright 2025 Paperzz