VB2019 バージョン情報 への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 たか  (社会人) 投稿日時 2024/2/29 08:41:30
ありがとうございます。

現時点では、
        ・・・
        Finally
            conn.Close()
            conn.Dispose()
        End Try
としています。

ex.GetType().FullName
も記述してみました。
とても参考になります。

「クローズ済オブジェクトの処理が無効です」
が発生したタイミングでは、SQL文の間違いとDo文でWhile~をコメントアウトしていたのかもしれません。
https://vbnetdb.net/odpnet/odpnet_dr_notclose.php
と同じ状況になっていたと思われます。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 20:07:55
> おそらくSQL文の間違いではなかったかと想像します。

うーん。SQL の記述ミスであれば、
>> MsgBox(ex.Message) では、「クローズ済オブジェクトの処理が無効です」と表示されました。
にはならない気がするのですけれどね。

OracleConnection や OracleDataReader がローカル変数ではなく、フィールド変数になっていたとか、
掲示板投稿時には書かれていない、何か別の処理があったんじゃないかと予想しますが。

もしも SQL 側が間違っているなら ExecuteReader の時点で ORA-xxx 系のエラーメッセージが出そうですし、
dr.Item のフィールド名やフィールド番号の指定ミスなら、また別のエラーになっていたと思うのですよ。


それと、ex.Message というのは、障害発生時の調査情報としては、必ずしも十分ではありません。
利用者向けの簡易表示ならばいざ知らず、開発者が障害個所を特定するために記録するためには、
ex.ToString() などを使った方が、より多くの情報を得られます。もし、StackTrace が冗長なのだとしても、
せめて ex.Message と共に ex.GetType().FullName を記録するようにしてみましょう。
先の回答でも、解析に『例外クラスの型名』と『例外メッセージの内容』が欲しいと書いていますよね。


で…それよりも問題なのは、Oracle に接続した後、そのカーソルやコネクションの後始末が行われていない点です。
掲示板に投稿する際に省略されただけならば良いのですが、使用後にはきちんと Close / Dispose を行いましょう。
Finally を使うかどうかはお好みで。
https://vbnetdb.net/odpnet/odpnet_dr_notclose.php
投稿者 たか  (社会人) 投稿日時 2024/2/28 17:21:00
2024/2/27 16:52:49に投降したソースに書き戻して、接続情報,SQLを実際のものにしてみたところ
問題なくデータの取得ができました・・・

前回投降した時点でもコネクションは確認できていたので、発生していた例外は、おそらくSQL文の間違いではなかったかと想像します。
(テーブル名またはフィールド名の間違い)

Do While dr.Read()
でも問題なく動作しました。

お騒がせしました。
ありがとうございました。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 13:53:11
> Do While dr.Read = True

この場合の Read メソッドは Boolean 型を返すメソッドですよね。

なので、「Do While dr.Read()」と「Do While dr.Read = True」は同義のはずです。
記述的には、むしろ前者の方が望ましいかと。
投稿者 たか  (社会人) 投稿日時 2024/2/28 13:21:09
魔界の仮面弁士さま

ありがとうございます。
OracleDataReaderの扱いが分かっておらず、Do Loop文がおかしかったようです。

            Do While dr.Read = True
                MsgBox(dr.Item("TANNM"))
            Loop

とすることで、例外が発生しなくなりました。

初期の問い合わせ内容からは異なる内容となってしまいましたが、とても参考になりました。
・ODP.NET
・複数の環境へのインストール
・データ取得
と、基本的な部分を動作させることができました。
ありがとうございました。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 11:35:55
おっとすれ違い。
今回、内部スタックトレースは追っても仕方ないので無視するとして:

> MsgBox(ex.Message) では、「クローズ済オブジェクトの処理が無効です」と表示されました。
OracleDataReader が閉じられた状態で、その中身を読みだそうとしているように見えますね。

DataTable に対して、table1.Load(dr) などを呼び出していたりはしないでしょうか。
こうした動作によって、IDataReader が閉じられてしまう可能性があります。

> Do While dr.Read()
あるいはデバッガ―上で、dr.Read() をウォッチ ペインやイミディエイト ペインで読み込ませていないでしょうか。
Read メソッドを呼ぶと現在行が進んでしまうので、ループ内で意図せず呼ばれると、副作用を引き起こします。

もしくはちょっと特殊ですが、Oracle の LONG型(可変長文字列型) や LONG RAW 型(可変長バイナリ型)を含むテーブルを
参照しようとした際、二回以上読みだそうとしたときに閉じられてしまう不具合があったかと思います。
(Oracle 側のパッチで修正されていた気がしますがうろ覚え)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 11:20:27
> Dim F_DATA01 As String = String.Empty
> Dim F_DATA02 As String = String.Empty
(中略)
> F_DATA01 = dr.Item("STAFFCODE")           ' ★
> F_DATA02 = dr.Item("STAFFNAME")           ' ★

たとえば、戻り値が DBNull だったということはないでしょうか?

でも、その場合の例外は System.InvalidCastException の
「型 'DBNull' から型 'String' への変換は無効です。」になるはずなので
いくらなんでも、気がつかないはずは無いか…。

SQL を見る限り、フィールド名のスペルミスでもなさそうですし、
やっぱり、エラーの詳細が追えないと分からないですね。
失敗の原因が、掲示板投稿時に端折ったり改編した箇所にあるという可能性もありえますし。

ひとまず型変換の問題を事前回避するため、Option Strict On モードで
コンパイルが通る状態にまで改修してみることをお奨めします。
投稿者 たか  (社会人) 投稿日時 2024/2/28 11:19:37
お世話になっております。自分でデバッグできるようにならないとですね・・・

MsgBox(ex.Message) では、「クローズ済オブジェクトの処理が無効です」と表示されました。

「出力」は、下記のとおりです。

'WindowsApp1.exe' (CLR v4.0.30319: DefaultDomain): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: DefaultDomain): 'C:\Users\WindowsApp1\bin\x86\Debug\WindowsApp1.exe' が読み込まれました。シンボルが読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.Remoting\v4.0_4.0.0.0__b77a5c561934e089\System.Runtime.Remoting.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Oracle.ManagedDataAccess\v4.0_4.121.2.0__89b483f429c47342\Oracle.ManagedDataAccess.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.Transactions.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll' が読み込まれました。
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.Wrapper.dll' が読み込まれました。
例外がスローされました: 'System.InvalidOperationException' (Oracle.ManagedDataAccess.dll の中)
例外がスローされました: 'System.BadImageFormatException' (System.Core.dll の中)
'WindowsApp1.exe' (CLR v4.0.30319: WindowsApp1.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_ja_b77a5c561934e089\mscorlib.resources.dll' が読み込まれました。モジュールがシンボルなしでビルドされました。
例外がスローされました: 'System.InvalidOperationException' (Oracle.ManagedDataAccess.dll の中)
例外がスローされました: 'System.BadImageFormatException' (System.Core.dll の中)
例外がスローされました: 'System.BadImageFormatException' (System.Core.dll の中)
例外がスローされました: 'System.InvalidOperationException' (Oracle.ManagedDataAccess.dll の中)
例外がスローされました: 'System.ObjectDisposedException' (System.dll の中)
プログラム '[1616] WindowsApp1.exe' はコード 0 (0x0) で終了しました。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 10:19:58
> 接続文字列を直接埋め込んでみました。

蛇足ですが、VB2015 以降なので $"~" を使って埋め込む方法も使えますね。
書式指定子も使える記法なので、埋め込み SQL の作成などでも役に立つかも。

' 改行を含めることも可能 
Dim oradb As String = $"
    User Id={oraUser};
    Password={oraPwd};
    Data Source=(DESCRIPTION=
        (ADDRESS_LIST =
            (ADDRESS =
                (PROTOCOL = TCP)
                (HOST = {oraHost})
                (PORT = 1521)
            )
        )
        (CONNECT_DATA =
            (SERVICE_NAME = {oraService})
        )
    );"

TextBox1.Text = oradb


とはいえこの記法でも、「" を埋め込むときに "" にエスケープしなければならない」とか
「改行を含む場合、インデント時の前方の余剰空白が邪魔になる」といった問題は生じますね。
(C#11 の raw-string lieral 構文が VB でも使えるなら、そのあたりも改善されるんですが…)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/28 09:52:07
> 「例外がスローされました」となってしまいます。
その例外の内容を具体的に教えてもらわないと、流石に判断できないですね…。
例外クラスの型名と、例外メッセージの内容を添えて提示頂けますか?

例外が InnerException を保持している場合は、その内容も再帰的に取得しておいてください。
投稿者 たか  (社会人) 投稿日時 2024/2/27 16:52:49
紹介いただいたサイトを参考に、Oracle.ManagedDataAccessを参照に追加し、接続文字列を直接埋め込んでみました。
結果として、前回認証に失敗していたPCからも認証ができました。
運用上、接続文字列を直接埋め込むことは特に問題ないと考えています。
しかし、OracleDataReaderオブジェクトからデータを読み込む時点で「例外がスローされました」となってしまいます。
コードを貼り付けますのでご確認いただけますでしょうか。
フォーム上のボタンをクリックすることで、接続からSQL発行までしていますが、「★」の部分で例外が発生します。

Imports Oracle.ManagedDataAccess.Client
Imports Oracle.ManagedDataAccess.Types

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim oraHost As String = "SERVERNAME"
        Dim oraService As String = "SERVICENAME"
        Dim oraUser As String = "USERNAME"
        Dim oraPwd As String = "PASSWORD"
        Dim strSQL As String = String.Empty
        Dim oradb As String = String.Empty

        Try

            oradb = "Data Source=(DESCRIPTION="
            oradb = oradb & "(ADDRESS_LIST ="
            oradb = oradb & "(ADDRESS = (PROTOCOL = TCP)"
            oradb = oradb & "(HOST = " & oraHost & ")"
            oradb = oradb & "(PORT = 1521)))"
            oradb = oradb & "(CONNECT_DATA ="
            oradb = oradb & "(SERVICE_NAME = " & oraService & ")));"
            oradb = oradb & "User Id=" & oraUser & ";"
            oradb = oradb & "Password=" & oraPwd & ";"

            Dim conn As New OracleConnection(oradb)
            Dim F_DATA01 As String = String.Empty
            Dim F_DATA02 As String = String.Empty

            conn.Open()

            strSQL = "Select STAFFCODE, STAFFNAME From M_STAFF"
            Dim cmd As New OracleCommand(strSQL, conn)
            cmd.CommandType = CommandType.Text

            MsgBox(conn.State.ToString) ' コネクションの確認

            Dim dr As OracleDataReader = cmd.ExecuteReader()

            Do While dr.Read()
                F_DATA01 = dr.Item("STAFFCODE")           ' ★
                F_DATA02 = dr.Item("STAFFNAME")           ' ★
                MsgBox(F_DATA01 & vbTab & F_DATA02)
            Loop

        Catch ex As Exception

        End Try

    End Sub
End Class
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/26 18:01:17
tnsnames.ora の読み取りに失敗しているのかもしれませんね。
TNS を使わず、接続文字列を直接埋め込んだ場合はどうなりますか?
http://starcat2014.blog.fc2.com/blog-entry-2.html

上記だと冗長すぎる場合は、簡易接続ネーミング・メソッド表記の
 Dim dataSource As String = host & ":" & port & "/" & serviceName
程度でも良いかと思います。
https://docs.oracle.com/cd/F19136_01/netag/configuring-naming-methods.html#GUID-E5B6BEB9-70BB-46FA-9F6C-BE575CD41B21


もしも直接埋め込んだ場合は接続できて、TNS 指定だと失敗する場合、
実行環境における別の tnsnames.ora を読み込んでいた…というケースもあります。
(x86/x64 とか 11g/19c とかで、複数の ORACLE_HOME があったパターンなど)
https://forums.oracle.com/ords/apexds/post/ora-12504-error-with-odp-net-4713

複数のクライアントがある場合は、tnsnames.ora をシンボリックリンクにして、フォルダ間で単一ファイルとしてしまうか、
あるいは環境変数 TNS_ADMIN 指定で tnsnames.ora の場所を明示するという手もあるかと。
投稿者 たか  (社会人) 投稿日時 2024/2/26 17:38:17
認証が失敗した際には、ORA-12504が発生しています。
その端末からDatabaseにtnspingを実行すると正常に応答があります。
Oracle Databaseは開発環境とは別のサーバで稼働しており、ポートは解放されています。

Oracleの環境として、Databaseは19c, Clientは11gを使用しています。
これまでは、oo4oを利用していたこともあり、ODP.NETへの移行を検討しているところです。

「Oracle.ManagedDataAccess.dll」も利用可能と思いますので、その方向で検討したいと思います。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/26 16:52:29
> メインのウィンドウは表示されるものの、認証はできません。
認証失敗時のエラーは、ORA-xxxx 系が返されますか?
それとも .NET 側のネットワーク例外やタイムアウト系だけですか?
監査(audit)ログやリスナーログに、何か記録されていますか?
ポート 1521 を開放していないということはないですか?
大文字小文字の違いは大丈夫ですか?
プラガブル環境の場合に CDB に繋ごうとしていませんか?


> VBの参照にて「Oracle.DataAccess.dll(4.112.4.0)」を追加しました。
.NET Framework 4.x 向け Oracle 11.2 用 ODP.NET Release 6 ですね。
Oracle Database 11.2 環境への接続目的ですか?


個人的には「Oracle.DataAccess.dll」の利用はお奨めしません。
代わりに、12g で登場した「Oracle.ManagedDataAccess.dll」の利用をお奨めします。(Oracle Database 11.2 以上への接続が可能)
https://www.nuget.org/packages/Oracle.ManagedDataAccess#versions-body-tab


前者は unmanaged driver や ODP.NET 管理対象外ドライバー と呼ばれます。
後者は managed driver や ODP.NET 管理対象ドライバー と呼ばれます。

前者は実行環境に、.NET の管理対象外となる Oracle Client のインストールが
必須となるため、ClickOnce との相性が悪いです。Oracle Instant Client を使うにしても、
32bit/64bit とでライブラリも別ですし、インストール後にも、ClickOnce の範囲外のところで
追加の設定作業が幾つか必要となる可能性があります。異なるバージョンの Oracle Client を
並行してインストールする場合も、管理が煩雑になりがちなのが難点。

既に導入済みのようなので釈迦に説法とは思いますが、導入手順の例を紹介しておきます。
https://blog.shibata.tech/entry/2014/10/24/074303
https://imatake.cfbx.jp/fswiki/wiki.cgi?page=Oracle%2FInstantClient


一方後者の場合、Oracle Client やネットワークライブラリを必要とせず、.NET 管理の 2 つの DLL だけで動作します。
.NET 管理ゆえに Side-by-side 実行に対応していますし、AnyCPU な純粋な .NET ライブラリのため、
ClickOnce との相性も良いかと思います。こちらは、以前の tnsnames.ora をそのまま使うこともできますが、
それと同様の接続エイリアス情報を machine.config や app.config 内に記述することもできるため、
利用環境への導入作業も比較的容易です。
https://www.oracle.com/jp/technical-resources/articles/dotnet/o24odp.html

.NET Standard 2.1 版の ODP.NET Core もあります。
https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/#versions-body-tab
投稿者 たか  (社会人) 投稿日時 2024/2/26 15:25:01
魔界の仮面弁士さま
回答ありがとうございます。
少し具体的に書いてみます。

現在、VBからODP.NETでOracleに接続するプログラムを書いています。
VBの参照にて「Oracle.DataAccess.dll(4.112.4.0)」を追加しました。
現時点では、認証の判定のみを記述して動作を確認しています。

VBのデバッグにて、User ID, Password, Data Sourceの値を変更しながら、
正しい組み合わせでのみ認証できることを確認。
次に、開発環境のあるPCでアプリケーションをセットアップして動作を確認。
ここまでは正しく動作しているようです。
さらに、開発環境とは異なる別PCにてアプリケーションをセットアップして動作を確認したところ、
メインのウィンドウは表示されるものの、認証はできません。
いずれのPCでもOracle Clientインストール済み,TNS名設定済みです。

別PCではうまく参照できていないのではないかと考えていますが・・・。「Oracle.DataAccess.dll」

参考にしているサイト
https://docs.oracle.com/cd/E16338_01/appdev.112/b56266/connecting.htm
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/23 08:18:03
> 別PCではインストールが完了するものの、メインのフォームが表示されず、ジタバタしていました。

発行されたのに、特定の環境では起動しない場合、依存ファイルや設定ファイルが不足している場合や、
特定のセキュリティ 製品(Kaspersky, Trendmicro 等)との相性上の理由、あるいは、
Windows Update の不具合などが理由で起動が阻害されているパターンなど様々な要因があり、
仔細調査の上、それぞれの事象に合わせて個別に対処が必要です。

起動時にエラーメッセージが出るものや、起動完了前にエラー表示もなく強制終了するケース、
イベントログにエラーが記録されるケースなど様々ではありますが、幾つかのケースを紹介しておきます。
Windows Update が原因の場合は、次回配信で修正されることが多いので、直近の更新分を消してやると回復するかもしれません。
https://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=11441&reno=11440&oya=11436&mode=msgview&page=0
https://twitter.com/Benshi_Orator/status/1660537176550150146
https://twitter.com/Benshi_Orator/status/1691619040530194933
https://twitter.com/Benshi_Orator/status/996931780304293888


• 何らかの理由で通信に失敗した場合、以前の中途半端なキャッシュが残ったままになることで、再インストールしても
 正しく動作しない状況が続いてしまうことがあります。この場合、コントロールパネルからアプリを削除した後で、
 %LocalAppData%\Apps\2.0\ にあるアプリをフォルダーごと消してから再インストールを試してみてください。
https://jpdscore.github.io/blog/deployment/fail-to-launch-clickonce-apps-after-updated/

• ClickOnce では起動しないが EXE コピーでは起動する場合、セキュリティ上の理由で起動阻害されている可能性があります。
 ◦ClickOnce の配布元を Web サイトにしている場合は、そのサイトを信頼済みサイトに登録してみる。
 ◦ネットワークをオフライン状態にした状態であれば起動できないかを試してみる。

• Windows 10 v1803 という古い環境限定でしたが、インストールした exe に、誤ってゾーン識別子の
 代替ストリームが付いてしまう事象が発生したことがあります。
 この場合、インストールされた exe を右クリックしてプロパティを開き、一番下にセキュリティ欄が出ているか確認してみてください。
 出ていた場合は、「許可する」にチェックを付けて保存することで、ゾーン識別子が削除されて起動するようになります。
 → ゾーン識別子を消さずとも、SmartScreen を [無効] にすると起動します(起動時にブロック警告は出る)。
  SmartScreen が [ブロック]や[警告]の場合は何も起動しない状態です(エラーメッセージもなし)。
  SmartScreen が有効でも、LANケーブルを抜いてオフラインにすると実行されるので、起動後にLANケーブルを戻すことで動きだします。
 → この事象は、ClickOnce アプリの新規インストールおよび自動更新時にのみ発生した問題でした。
  Win10 1709 の頃にインストールしたアプリは、OS が 1803 に更新されてもゾーン識別子が無いままなので、正常に動作します。
  (その後、Windows Update によって 1803 環境でも再発しないようになったので、過去の事例ではありますが)

• WPF の場合、グラフィックドライバーが原因でうまく起動しないことがあります(ClickOnce でなくとも同じ)。
 最近の環境であればほとんど問題ないとは思いますが、グラフィック機能の弱い古いサーバー環境などでは
 グラフィック ドライバーの更新などによって改善することがあります。

• 32bit な ActiveX コントロールを使っているプロジェクトが起動しないという問題があって調べたところ、
 古いプロジェクトからマイグレーションしたプロジェクトであったが故に、その exe が AnyCPU ビルドだったという
 事故がありました(リリース当時は AnyCPU32bitPreferred モードが存在しないが、32bit OS が全盛だったため問題が発覚しなかった)。
 この時は x86 版な別アプリとして発行しなおすことで回復させましたが、事情があってリビルドできない場合は、
 インストールされた exe を、CoreFlags.exe で強制的に「-32BITREQ+」して exe を書き換えるという暫定措置で対応しました。

• 3 年前ですが、Acronis True Image 2020 / Acronis Active Protection という製品との相性問題を経験しました。
 (自分自身は同製品を見たことが無いのですが、その製品を止めてもらったら動き出した)
 製品のログを見ると
  「次のアプリケーションがブラックリストに登録されました:」
  「プロセスがブロックされました:」
  「複数のフォルダの内容が、互いに類似する疑わしいパターンによって変更されました」
 と記録されていました。ClickOnce なので、バージョンアップ時には Apps\2.0\ 配下に複数のフォルダーを作るし、
 類似したファイルも配置されるので、相性が悪い…。(今は改善されているのかな?)
 → 同様の事象は、Kaspersky を使っているユーザーでも発生したことがあります。

• 起動障害とは別件ですが、OS を再起動すると ClickOnce アプリが未インストール状態に戻ってしまい、
 ショートカットから起動すると、毎回、新規インストールが走ってしまったり、あるいはショートカットファイル自体が
 消えてしまうという問題が起きたことがおります。(Windows Update による一時的な問題だったので、その後の自動更新で回復)
https://twitter.com/Benshi_Orator/status/1690941144522539008

• 起動障害とは別件ですが、設定情報を My.Settings.Save しているアプリの場合、ごく稀に、設定ファイルが
 バイナリ 00 で埋め尽くされることがあるようです。破損した user.config ファイルを手動あるいはプログラムから削除すれば回復します。
https://twitter.com/Benshi_Orator/status/1590999779177541633
https://twitter.com/Benshi_Orator/status/1683299933716353024
投稿者 たか  (社会人) 投稿日時 2024/2/22 23:16:54
配布の方法にもいろいろあるわけですね。

これまでは社内のファイルサーバに「発行」をしていました(ClickOnce)。クライアントに一度インストールすれば自動でバージョンアップもできて管理は楽でした。

久しぶりにVBで開発することになり、ClickOnceで発行してみたのですが、別PCではインストールが完了するものの、メインのフォームが表示されず、ジタバタしていました。

ご案内いただいたサイトをじっくり調べてみます。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/2/22 21:39:01
> ユーザ側から見たバージョンは[公開するバージョン]でしょうか。
> この[公開するバージョン]を取得するコードが知りたいです。

「公開するバージョン」は ClickOnce 配布する場合の管理情報です。
アプリケーションそのものの情報ではありませんので、作成した EXE ファイル等を
直接コピー配布するような場合には用いられませんが、よろしいですか?

ClickOnce の仕組みはこちら。VS2005 時代の情報なので、インストーラーのフォルダー階層等は
今の物とは幾分違っていますが、考え方は今でも同じです。
https://atmarkit.itmedia.co.jp/ait/articles/0603/11/news018.html

公開バージョンをプログラムから得るためには、まず、自アプリが ClickOnce 発行されたものであるかどうかを確認しなけばなりません。
そのための判定処理はこう書きます。
If My.Application.IsNetworkDeployed Then

My を使いたくない場合は、 System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed でも同じです。
その性質上、Visual Studio からのデバッグ実行ではなく、実際に発行してインストールされたアプリから呼ばれないと True になりません。

上記が True であることが判明したうえで、「公開するバージョン」をこのように取得します。
IsNetworkDeployed が False の時に呼ぶとエラーになりますのでご注意ください。
'System.Version クラスのインスタンスを得る 
Dim ver1 = My.Application.Deployment.CurrentVersion
Dim ver2 = My.Application.Deployment.UpdatedVersion

My.Application.Deployment のかわりに
System.Deployment.Application.ApplicationDeployment.CurrentDeployment でも構いません。

UpdatedVersion と CurrentVersion は、ほとんどの場合、同じバージョンを返しますが、
新しい更新がインストールされていても、まだアプリケーションを再起動していない場合には、
UpdatedVersion は CurrentVersion と異なります。新しい更新が存在するかどうかは、
If My.Application.Deployment.CheckForUpdate() Then で判断できます。

> VB2019でプロジェクトのプロパティを開くと、
> [アプリケーション]-[アセンブリ情報]-[アセンブリバージョン]
> [アプリケーション]-[アセンブリ情報]-[ファイルバージョン]
> [公開]-[公開するバージョン]
> など、複数の「バージョン」があります。
EXE ファイルそのものに含まれるバージョンにつきましては、こちらが参考になるでしょう。
https://dobon.net/vb/dotnet/file/myversioninfo.html
https://dobon.net/vb/dotnet/file/fileversion.html
投稿者 たか  (社会人) 投稿日時 2024/2/22 17:19:07
VB初心者です。

VB2019でプロジェクトのプロパティを開くと、
[アプリケーション]-[アセンブリ情報]-[アセンブリバージョン]
[アプリケーション]-[アセンブリ情報]-[ファイルバージョン]
[公開]-[公開するバージョン]
など、複数の「バージョン」があります。

ユーザ側から見たバージョンは[公開するバージョン]でしょうか。
この[公開するバージョン]を取得するコードが知りたいです。