DOBON.NET DOBON.NETプログラミング掲示板過去ログ

VB2010で作成したアプリケーションをファイルサーバ上で共有したい

環境/言語:[WindowsServer2008R2 Windows7 32bit VB2010 .NetFrameWork4.5.1]
分類:[.NET]

お世話になります。
初めて投稿いたします。

VB6.0で作成したアプリケーションをVB2010で再構築しました。
VB2010で作成したアプリケーションをVB6.0で運用していたようにファイルサーバ上で(実行ファイルを)共有したいと考えていますが、そもそも可能でしょうか?ネットで検索してもあまりネタが無いので、.Netになってからは推奨しない運用方法となっているのか知りたいです。

また、[http://www.atmarkit.co.jp/fdotnet/special/vb6tovb2005mig03/vb6tovb2005mig03_01.html]では、
・コードアクセスセキュリティというセキュリティ機能が追加された・・・。
・配布方法にClickOnceが追加された・・・等、記載されており、ファイルサーバ上で(実行ファイルを)共有しない方が良いと感じとれます。

実際、VB2010で作成したアプリケーションをファイルサーバ上で(実行ファイルを)共有させ、3台のクライアントパソコンから実行してみました。
一見、問題無かったのですが、暫く操作するうちにDB接続エラーが表示されました。これは特定のパソコンで発生するものではありませんでした。
パソコンを再起動すると、回復する場合があります。
エラー内容は、下記の通りです。DBにはWindows認証、SQLServer認証どちらでADO接続してもエラーとなります。

<エラー内容>
Just-In-Time (JIT) デバッグを呼び出すための詳細については、
ダイアログ ボックスではなく、このメッセージの最後を参照してください。
************** 例外テキスト **************
System.InvalidCastException: String "ComAdoConnect" から型 'Double' への変換は無効です。 ---> System.FormatException: 入力文字列の形式が正しくありません。
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat)
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat)〜


<試した事>
・ウィルス対策ソフトを無効にしても事象変わらず(サーバ、クライアントパソコン)
・SQLServerで使用するポートをWindowsファイアウォールに登録済(サーバ)
・WindowsファイアウォールをOFFにしても事象変わらず(サーバ)

【稼働環境】
・サーバ:[WindowsServer2008R2 Std sp1 、SQLServer2008R2 Std Sp3、.NET Framework4.5.1
・クライアント:Windows7 32bit、VisualStudio2010、VisualBasic2010、.NET Framework4.5.1

以上、言葉足らずで恐縮ですが有識者の方、よろしくお願いします。
■No32714に返信(nuno4さんの記事)
> System.InvalidCastException: String "ComAdoConnect" から型 'Double' への変換は無効です。 ---> System.FormatException: 入力文字列の形式が正しくありません。

極端な話、上記のメッセージは
 Dim o As Object = "ComAdoConnect"
 If o <> 0 Then
というコードでも発生しますね。

型変換エラーであるということから、そもそもプログラムの記述に
問題がありそうです。たとえば、エラー発生時の回復処理
(Resume コードあるいは Try Catch など)に問題があるとか。

まずは、「Option Strict On」でコンパイルが通るように
コードを見直してみて下さい。それでも回避できないようなら、
エラーが発生する箇所のソースコードを提示いただければ、
具体的な指摘ができるかもしれません。
魔界の仮面弁士様
返信ありがとうございます。
コードは以下の通りです。★の箇所でエラーメッセージを表示しています。開発環境では事象は発生しません。複数のパソコンで共有している影響なのか不明です…。
宜しくお願い申し上げます。


Public Class mdlADOConnection

Private Shared ADOCon As ADODB.Connection 'ADOコネクションオブジェクト
Private intAdoErr As Integer 'ADOエラーケース
Private Const INIFILENAME = "\TEST.ini" '設定ファイル名
Private Const KENGEN_ERR_NO = -2147217911 'エラー番号(テーブル操作権限無)
'INIファイルを読み込むための関数の宣言
Declare Function GetPrivateProfileString _
Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
'環境変数取得構造体
Public Structure typEnv
Dim strServerName As String 'サーバー名
Dim strDatabaseName As String 'データベース名
Dim bolRet As Boolean '取得フラグ(True:正常, False:エラー)
End Structure
#Region " { GetEnv 環境変数の取得 } "
'******************************************************************************************
' モジュール名称 :GetEnv
' 機能概要    :環境変数の取得
' 引数      :
' 戻り値     :正常 :GetEnv.bolRet = True
'         :エラー:GetEnv.bolRet = False
'******************************************************************************************
Public Shared Function GetEnv() As typEnv
Dim intRet As Integer
Dim strCurPath As String
Dim strGetBuff As String
Dim strIniPath As String

If GetEnv.bolRet Then
Return Nothing
Exit Function
End If

'初期化
GetEnv.strServerName = ""
GetEnv.strDatabaseName = ""
GetEnv.bolRet = True

Try
'iniファイル存在チェック
'strIniPath = CurDir()
strIniPath = My.Application.Info.DirectoryPath()
'strIniPath = System.Windows.Forms.Application.StartupPath '--ADD 2014/11/10

strCurPath = strIniPath & INIFILENAME

'MsgBox(strCurPath)

'If Len(Dir(strCurPath)) < 1 Then '--DEL 2014/11/07
If Not System.IO.File.Exists(strCurPath) Then '--ADD 2014/11/07
MsgBox("設定ファイルが存在しません。" & vbCrLf & strCurPath, vbCritical)
GetEnv.bolRet = False
Exit Function
End If

'サーバー名取得
strGetBuff = New String(" ", 1024)
intRet = GetPrivateProfileString("Connect", "ServerName", "", strGetBuff, strGetBuff.Length, strIniPath & INIFILENAME)
If intRet <> 0 Then
GetEnv.strServerName = strGetBuff.Substring(0, strGetBuff.IndexOf(vbNullChar))
Else
MsgBox("環境変数の取得に失敗しました。", vbOKOnly + vbCritical, "エラー")
GetEnv.bolRet = False
Exit Function
End If

'データベース名取得
strGetBuff = New String(" ", 1024)
intRet = GetPrivateProfileString("Connect", "DatabaseName", "", strGetBuff, strGetBuff.Length, strIniPath & INIFILENAME)
If intRet <> 0 Then
GetEnv.strDatabaseName = strGetBuff.Substring(0, strGetBuff.IndexOf(vbNullChar))
Else
MsgBox("環境変数の取得に失敗しました。", vbOKOnly + vbCritical, "エラー")
GetEnv.bolRet = False
Exit Function
End If

Catch ex As Exception
MsgBox("システムエラー:" & Err.Number & vbCrLf & vbCrLf _
& "メッセージ:" & ex.Message & vbCrLf & vbCrLf _
& "プロシージャ:cmdMaigara_Click", vbOKOnly + vbCritical, "システムエラー")
GetEnv.bolRet = False

End Try

End Function
#End Region

#Region " { ComAdoConnect データベース接続 } "
'******************************************************************************************
' モジュール名称 :ComAdoConnect
' 機能概要    :データベース接続
' 引数      :strServerName(サーバー名称)
'         :strDatabaseName(データベース名称)
'         :strUserName(ユーザー名称)
'         :strPassword(パスワード)
' 戻り値     :True(-1): 正常
'         :False(0): エラー
'******************************************************************************************
Public Shared Function ComAdoConnect() As Boolean
Dim intCount As Integer = 0

Try
'ADOコネクション
ADOCon = New ADODB.Connection

'INIファイル読込
If Not GetEnv.bolRet Then
Return False
End If

'接続情報設定
ADOCon.ConnectionTimeout = 15 '接続タイムアウト
ADOCon.Provider = "SQLOLEDB" 'プロバイダ名
ReTry:
'Windows認証を利用して接続
'ADOCon.Properties("Data Source").Value = GetEnv.strServerName
'ADOCon.Properties("Initial Catalog").Value = GetEnv.strDatabaseName
'ADOCon.Properties("Integrated Security").Value = "SSPI"
'ADOCon.Properties("persist security info").Value = True
'ADOCon.Open()

'SQL Server認証を利用して接続
ADOCon.Properties("Data Source").Value = GetEnv.strServerName
ADOCon.Properties("Initial Catalog").Value = GetEnv.strDatabaseName
ADOCon.Properties("User ID").Value = "xx"
ADOCon.Properties("Password").Value = "xxxxxx"
ADOCon.Properties("persist security info").Value = True
'MsgBox(ADOCon.ConnectionString)
ADOCon.Open()

Return True

Catch ex As Exception
'エラー情報クリア
ADOCon.Errors.Clear()
intCount += 1
If intCount < 5 Then
Err.Clear()
System.Threading.Thread.Sleep(3000) '3秒待つ
'ADOCon.ConnectionString = ""
GoTo ReTry '再度接続
End If
★MsgBox("データベースの接続に失敗しました。", vbOKOnly,"ComAdoConnect" + Err.Number + Err.Description)
Call ComAdoError()
Return False

End Try

End Function
#End Region
まだ調査中ですが、エラーの詳細は下記の通りです。
Sドライブは、ファイルサーバ(実行ファイル格納フォルダ)です。
ADODB.dll辺りがあやしいのかな・・・


エラー:-2147467259[DBNETLIB][ConnectionOpen(Connect()).]SQL Serverが存在しないか、アクセスが拒否されました。

Just-In-Time (JIT) デバッグを呼び出すための詳細については、
ダイアログ ボックスではなく、このメッセージの最後を参照してください。

************** 例外テキスト **************
System.InvalidCastException: String "ComAdoConnect" から型 'Double' への変換は無効です。 ---> System.FormatException: 入力文字列の形式が正しくありません。
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat)
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat)
場所 Common.mdlADOConnection.ComAdoConnect()
場所 prjGaiGen.frmTouroku.frmTouroku_Load(Object sender, EventArgs e)
場所 System.EventHandler.Invoke(Object sender, EventArgs e)
場所 System.Windows.Forms.Form.OnLoad(EventArgs e)
場所 System.Windows.Forms.Form.OnCreateControl()
場所 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
場所 System.Windows.Forms.Control.CreateControl()
場所 System.Windows.Forms.Control.WmShowWindow(Message& m)
場所 System.Windows.Forms.Control.WndProc(Message& m)
場所 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
場所 System.Windows.Forms.ContainerControl.WndProc(Message& m)
場所 System.Windows.Forms.Form.WmShowWindow(Message& m)
場所 System.Windows.Forms.Form.WndProc(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
場所 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** 読み込まれたアセンブリ **************
mscorlib
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18444 built by: FX451RTMGDR
コードベース:file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
XXXX取引
アセンブリ バージョン:1.0.0.0
Win32 バージョン:1.0.0.0
コードベース:file:///S:/xxxxx.EXE
----------------------------------------
Microsoft.VisualBasic
アセンブリ バージョン:10.0.0.0
Win32 バージョン:11.0.50938.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.34238 built by: FX452RTMGDR
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Windows.Forms
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.34234 built by: FX452RTMGDR
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.34245 built by: FX452RTMGDR
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
Microsoft.VisualBasic.PowerPacks.Vs
アセンブリ バージョン:10.0.0.0
Win32 バージョン:10.0.30319.1
コードベース:file:///C:/windows/assembly/GAC_MSIL/Microsoft.VisualBasic.PowerPacks.Vs/10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.PowerPacks.Vs.dll
----------------------------------------
Common
アセンブリ バージョン:1.0.0.0
Win32 バージョン:1.0.0.0
コードベース:file:///S:/%E5%AE%9F%E8%A1%8C/Common.DLL
----------------------------------------
ADODB
アセンブリ バージョン:7.0.3300.0
Win32 バージョン:7.10.6070
コードベース:file:///C:/windows/assembly/GAC/ADODB/7.0.3300.0__b03f5f7f11d50a3a/ADODB.dll
----------------------------------------
mscorlib.resources
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0.0_ja_b77a5c561934e089/mscorlib.resources.dll
----------------------------------------
Microsoft.VisualBasic.resources
アセンブリ バージョン:10.0.0.0
Win32 バージョン:11.0.50938.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic.resources/v4.0_10.0.0.0_ja_b03f5f7f11d50a3a/Microsoft.VisualBasic.resources.dll
----------------------------------------
System.Windows.Forms.resources
アセンブリ バージョン:4.0.0.0
Win32 バージョン:4.0.30319.18408 built by: FX451RTMGREL
コードベース:file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_ja_b77a5c561934e089/System.Windows.Forms.resources.dll
----------------------------------------

************** JIT デバッグ **************
Just-In-Time (JIT) デバッグを有効にするには、このアプリケーション、
またはコンピューター (machine.config) の構成ファイルの jitDebugging
値を system.windows.forms セクションで設定しなければなりません。
アプリケーションはまた、デバッグを有効にしてコンパイルされなければ
なりません。

例:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

JIT デバッグが有効なときは、このダイアログ ボックスで処理するよりも、
ハンドルされていない例外はすべてコンピューターに登録された
JIT デバッガーに設定されなければなりません。
2014/11/19(Wed) 22:55:11 編集(投稿者)

■No32722に返信(nuno4さんの記事)
> System.InvalidCastException: String "ComAdoConnect" から型 'Double' への変換は無効です。 ---> System.FormatException: 入力文字列の形式が正しくありません。

こっちは本質のエラーではありません。
VB の文字列連結は & 演算子のはずですから、 + 演算子で数値として足し算するために "ComAdoConnect" を数値と解釈しようとして例外が発生しているだけでしょう。
これを直してもエラーメッセージがちゃんと表示されるようになるだけなので、本質のエラーを解消しないといけません。

(+ 演算子で文字列としてつなげたいなら、CStr で文字列型に明示的に変換しておかないといけません)


> エラー:-2147467259[DBNETLIB][ConnectionOpen(Connect()).]SQL Serverが存在しないか、アクセスが拒否されました。

接続に関する設定やアクセス権周りを見直していただくところからでしょうか。
■No32718に返信(nuno4さんの記事)
どこから突っ込むべきか悩ましいコードですね…。

コメント部と実装に食い違いもありますし、何より
VB5〜VB6 あたりで作られた実装を、VB.NET の文法に
直訳で置き換えたような、危うい印象を受けました。



それはさておき、今回の問題は、そもそも VB.NET へと
翻訳する前から混入していた、潜在的なバグでしょう。


> ★MsgBox("データベースの接続に失敗しました。", vbOKOnly,"ComAdoConnect" + Err.Number + Err.Description)

上記のコードは、 VB6 で
  Call MsgBox("データベースの接続に失敗しました。", vbOKOnly, "ComAdoConnect" + Err.Number + Err.Description)
と書いたとしても、『型が一致しません。』の実行時エラーになるはずです。


理由は既に指摘されていますので蛇足的になりますが、VB では
  『文字列型 + 数値型』 は 『CDbl(文字列型) + 数値型』に
  『数値型 + 文字列型』 は 『数値型 + CDbl(文字列型)』に
と、「暗黙の型変換」された上で「足し算」されるためです。


※「数値型」が VB6 の 通貨型 の場合は、CDbl を CCur と読み替えます。
※「数値型」が VB6 の 10進型 の場合は、CDbl を CDec と読み替えます。
※「数値型」が VB.NET の 10進型 の場合は、CDbl を CDec と読み替えます。


文字列連結するなら、「& 演算子」を使いましょう。
今回のケースなら、String.Format を使うのも良いですね。


同種の問題を防ぐためにも、一度「Option Strict On」を指定してコンパイルし、
データ型を意識したコーディングに慣れておくことをお奨めしておきます。



ついでなので、その他の箇所についても指摘:


> 'INIファイルを読み込むための関数の宣言
ここの掲示板の利用方法には
 『半角カナは使用しないでください。文字化けの原因になります。』
とあります。次回以降ご留意下さい。


> Declare Function GetPrivateProfileString _
> Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
可能であれば、ANSI 版よりも Wide 版を使うことを検討してみてください。
Win9x を相手にするなら ANSI 版の方が良いですが、今となっては絶滅種の OS ですし。


> Private Shared ADOCon As ADODB.Connection 'ADOコネクションオブジェクト
ADO の利用は極力避けましょう。ADO.NET への移行を強くおすすめします。
どうしても ADODB を使うなら、COM 解放の手順も必要ですよ。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=7478&KLOG=19


> strCurPath = strIniPath & INIFILENAME
アプリがルートフォルダにあった場合、
 strCurPath = "C:\\TEST.ini"
のように余計な \ が付くことになりそう。


> Catch ex As Exception
> MsgBox("システムエラー:" & Err.Number & vbCrLf & vbCrLf _
> & "メッセージ:" & ex.Message & vbCrLf & vbCrLf _
> & "プロシージャ:cmdMaigara_Click", vbOKOnly + vbCritical, "システムエラー")
> GetEnv.bolRet = False
>
> End Try
すべての Exception を無条件で Catch してしまっているようですが、
そももこの例外処理は、Try ブロック内のどの行でエラーが発生することを
想定して配置したものでしょうか?


問題と思われる箇所:

・例外を「握りつぶす」コードとなっているため例外が発生しても原因箇所を特定しにくい
・「プロシージャ」表記が不自然(そもそも、呼び出し元が知りたいなら StackTrace を辿れば済む)
・MsgBox の第二引数は、本来は + ではなく Or で繋ぐべき



> Public Shared Function ComAdoConnect() As Boolean
> Try
> 'ADOコネクション
> ADOCon = New ADODB.Connection
状態確認することなく ADOCon 変数を上書きしていますが、本当にそれで大丈夫でしょうか。

・このメソッドが一度しか呼ばれない前提なら、この処理をコンストラクタに置くことを検討
・後で呼びなおす必要があるなら、シングルトンパターンやモノステートパターンなどで実装



> #Region " { ComAdoConnect データベース接続 } "
この後に続くコメントに不備があるので、整備しておきましょう。
ついでに、「'''」で書き始める『ドキュメントコメント』の利用を推奨。


> System.Threading.Thread.Sleep(3000) '3秒待つ
Form を扱うアプリの場合、Sleep メソッドの利用は避けてください。
背後でやりとりされる Windows Messages の流れを阻害してしまう可能性があります。
(UI 要素を伴わないワーカースレッドから呼ぶ分には構いませんが)
Azulean様

>VB の文字列連結は & 演算子のはずですから、 + 演算子で数値として足し算するために "ComAdoConnect" を数値と解釈しようとして例外が発生しているだけでしょう。
>これを直してもエラーメッセージがちゃんと表示されるようになるだけなので、本質のエラーを解消しないといけません。

ありがとうございました。上記の通りでした。(演算子を&に変更し、回復)
以後、注意します。

>エラー:-2147467259[DBNETLIB][ConnectionOpen(Connect()).]SQL Serverが存在しないか、アクセスが拒否されました。
>>接続に関する設定やアクセス権周りを見直していただくところからでしょうか。

演算子修正後、エラーが出なく無くなりました。(何故だか・・・)
暫くテストを続けてみます。ありがとうございました。



魔界の仮面弁士様

コードについてのご指摘ありがとうございます。
奥が深い・・・。何でそんなに詳しいのですか?

今後は、ADO.NETに書き替えていく予定です。

また、「VB2010で作成したアプリケーションをファイルサーバ上で共有できるか?」について、社内で聞いて回ったところ、他ユーザ実績がありという事が分かったので「共有できる」認識しています。

今後もお世話になると思います。
宜しくお願いいたします。
Azulean様
魔界の仮面弁士様

ご支援ありがとうございました。
今後も宜しくお願いします。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板