質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

4506閲覧

VBでプロセスの開始と終了をしているとたまに「動作を停止しました」エラーが出る。

ot2os

総合スコア23

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2019/07/30 06:41

●やりたいこと
何かしらの不具合で残留しているプロセスを一括で強制終了し、ついでに必要なプログラムを実行するプログラム(以下TaskCNT.exe)を作成しています。

TaskCNT.exeの実行時に時折「TaskCNTは動作を停止しました」エラーが発生してしまいます。
該当エラー発生時刻と思われるタイミングで、[イベントビューア]には下記の記録がありました。

障害が発生しているアプリケーション名: TaskCNT.exe、バージョン: 1.1.1.0、タイム スタンプ: 0x5d3a9089
障害が発生しているモジュール名: KERNELBASE.dll、バージョン: 10.0.14393.3085、タイム スタンプ: 0x5d1d7bde
例外コード: 0xe0434352
障害オフセット: 0x000dc1e2
障害が発生しているプロセス ID: 0x2708
障害が発生しているアプリケーションの開始時刻: 0x01d545a7464f77ec
障害が発生しているアプリケーション パス: C:\Users\800001\Documents\Tool\TaskCNT.exe
障害が発生しているモジュール パス: C:\windows\System32\KERNELBASE.dll
レポート ID: c943f0d1-f5b3-44b1-b5af-7e4d1721eb9f
障害が発生しているパッケージの完全な名前:
障害が発生しているパッケージに関連するアプリケーション ID:

「TaskCNTは動作を停止しました」エラーが出ているとTaskCNT.exeが終了ずに残った状態になってしまうため、エラーが出ないようにするかエラーを無視して動作するようにしたいです。
エラーの発生タイミングや原因が全く分からず、発生も毎回ではなく同じプロセスを実行させてもたまに出たり出なかったりします。

●調べたこと
また、Visual Studio でデバッグ中、TaskCNTからExcelマクロを実行した際、Excelマクロが何かしらの原因でエラーが発生したり強制終了したときにTaskCNT内のxlApp.Run(bookName & "!" & mtd)の部分で下記のエラーが出ることに気づきました。

型 'System.Runtime.InteropServices.COMException' のハンドルされていない例外が Microsoft.VisualBasic.dll で発生しました

追加情報:リモート プロシージャ コールに失敗しました。 (HRESULT からの例外:0x800706BE)

そこで、マクロやプロセスを実行する部分をまるっとTryで括るとマクロ強制終了時にエラーは出ずに本プログラムも正常に終了します。
しかし、肝心のKERNELBASE.dllが原因の「TaskCNTは動作を停止しました」エラーが不定期で発生する現象は直らず。

以下、ソースコードです。

VB

1Imports System.Management 2 3Module Module1 4 5 'メイン関数 6 Sub Main() 7 Dim Current_dir As String 8 Dim tgt_process As Object, tgt As String 9 10 'カレントディレクトリ取得 11 Current_dir = My.Application.Info.DirectoryPath 12 Console.WriteLine(Current_dir) 13 14 '終了対象プロセスを取得 15 tgt_process = Load_Settings(Current_dir & "\kill.ini") 16 If IsArray(tgt_process) Then 17 'すべてのプロセス一覧で実施する 18 For Each tgt In tgt_process 19 Dim arg As Object = Split(tgt, "?") 20 21 'tgtのプロセスを取得 22 Dim ps As System.Diagnostics.Process() = 23 System.Diagnostics.Process.GetProcessesByName(arg(0)) 24 25 If UBound(arg) = 0 Then 'ユーザ名指定なくプロセス終了 26 For Each p As System.Diagnostics.Process In ps 27 'プロセスを強制的に終了させる 28 p.Kill() 29 Next 30 ElseIf UBound(arg) = 1 Then 'ユーザ名指定でプロセス終了 31 '対象のユーザー名のみ強制終了 32 pkill_by_user(arg(1), ps) 33 End If 34 Next 35 Else 36 Console.WriteLine("kill.iniの記載が見当たりません。") 37 End If 38 39 '起動対象プロセスを取得 40 tgt_process = Load_Settings(Current_dir & "\launch.ini") 41 If IsArray(tgt_process) Then 42 'すべてのプロセス一覧で実施する 43 For Each tgt In tgt_process 44 Dim arg As Object = Split(tgt, "?") 45 46 '相対パスを絶対パスにする 47 System.Environment.CurrentDirectory = Current_dir 48 arg(0) = System.IO.Path.GetFullPath(arg(0)) 49' Try '★←ここをTryで括るとマクロ強制終了時にエラーは出ないものの、原因不明のKERNELBASE.dllエラーは直らず 50 If UBound(arg) = 2 Then 'Excelマクロ実行 51 Call CallMacro(arg(0), arg(1), arg(2)) 52 ElseIf UBound(arg) = 3 Then 'Excelマクロ実行(セーブフラグ付き) 53 Call CallMacro(arg(0), arg(1), arg(2), arg(3)) 54 ElseIf UBound(arg) = 0 Then 'プロセス起動 55 'tgtのプロセスを起動 56 Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(tgt) 57 End If 58' Catch ex As Exception 59' Console.WriteLine("プロセス「" & tgt & "」が見つかりません。") 60' End Try 61 62 Next 63 Else 64 Console.WriteLine("launch.iniの記載が見当たりません。") 65 End If 66 67 '#If DEBUG Then 68 ' Console.WriteLine("続行するには何かキーを押してください...") 69 ' Console.ReadKey() 70 '#End If 71 End Sub 72 73 74 '設定ファイルを読み込む 75 Function Load_Settings(ByVal fileName As String) 76 Dim tmp_line As String, arynum As Long = 0, Ans_vrt = New String() {""} 77 78 Load_Settings = "" '戻り値をリセット 79 80 If System.IO.File.Exists(fileName) Then '設定ファイルが存在する場合のみ読み出す 81 'fileNameをShift-JISコードとして開く 82 Dim sr As New System.IO.StreamReader(fileName, 83 System.Text.Encoding.GetEncoding("shift_jis")) 84 '内容を一行ずつ読み込む 85 While sr.Peek() > -1 86 tmp_line = sr.ReadLine() 87 tmp_line = Trim(tmp_line) 88 '#から始まっていたらエスケープ文字と判断 89 If Left(tmp_line, 1) <> "#" And Len(tmp_line) > 0 Then 90 ReDim Preserve Ans_vrt(arynum) 91 Ans_vrt(arynum) = tmp_line 92 arynum = arynum + 1 93 End If 94 End While 95 96 '内容が何か入っていたら実施 97 If arynum > 0 Then 98 Load_Settings = Ans_vrt '戻り値を出す 99 End If 100 End If 101 102 End Function 103 104 'Excelのマクロを実行する 105 Sub CallMacro(ByVal fileName As String, ByVal bookName As String, ByVal mtd As String, Optional ByVal saveE As Boolean = True) 106 ' Excel.Application の新しいインスタンスを生成する 107 Dim xlApp As New Object 108 Dim xlBooks As Object 109 110 xlApp = CreateObject("Excel.Application") 111 xlBooks = xlApp.Workbooks 112 113 ' xlApplication から WorkBooks を取得する 114 ' 既存の Excel ブックを開く 115 xlBooks = xlApp.Workbooks 116 xlBooks.Open(fileName) 117 118 ' Excel 表示有無 119 xlApp.Visible = False 120 '保存しますかダイアログ非表示 121 xlApp.DisplayAlerts = False 122 123 ' マクロを実行する 124 xlApp.Run(bookName & "!" & mtd) '★←マクロが強制終了するとここでエラー 125 126 'セーブフラグがあれば保存する 127 If saveE Then 128 xlBooks(1).Save() 129 End If 130 131 ' Excel を終了する 132 xlApp.Quit() 133 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) 134 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) 135 End Sub 136 137 '特定ユーザーのプロセスを終了する 138 Sub pkill_by_user(ByVal tgt_user As String, ByVal ps As System.Diagnostics.Process()) 139 Dim id_tgt_user = New String() {""}, ui As Long = 0 140 Dim mc As New System.Management.ManagementClass("Win32_Process") 141 Dim moc As System.Management.ManagementObjectCollection = mc.GetInstances() 142 Dim mo As System.Management.ManagementObject 143 For Each mo In moc 144 Dim id As String = mo("ProcessId").ToString() 145 146 Dim methodName(1) As String 147 mo.InvokeMethod("GetOwner", methodName) 148 Dim user As String = methodName(0) 149 Dim domain As String = methodName(1) 150 151 If tgt_user = user Then 152 ReDim Preserve id_tgt_user(ui) 153 id_tgt_user(ui) = id 154 ui = ui + 1 155 End If 156 Next mo 157 158 If ui > 0 Then 159 For Each p As System.Diagnostics.Process In ps 160 For Each u As String In id_tgt_user 161 'プロセスID一致検索 162 If p.Id = u Then 163 'プロセスを強制的に終了させる 164 p.Kill() 165 End If 166 Next 167 Next 168 End If 169 End Sub 170 171End Module

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kenshirou

2019/08/01 07:06

恐らく、KERNELBASE.dllのエラーが出ているのは、何らかの理由でプロセスのKillがうまくいかなかったのではないかと思います。 ところで、何のプロセスをKillしようとしていますか? 例えば、何らかの理由でExcelのプロセスが残ってしまい、これをKillしようとしていますか? そうであれば、ReleaseComObjectを行うべきオブジェクトが足りていないようにも思います。 (例えば、xlBooks(1)に該当するオブジェクトがReleaseComObjectされていないように見受けられます。) もし違っていたらゴメンナサイ。
ot2os

2019/08/06 08:43

> 恐らく、KERNELBASE.dllのエラーが出ているのは、何らかの理由でプロセスのKillがうまくいかなかったのではないかと思います。 ありがとうございます。 プロセスのkill部分も併せてまるっとTryで括ると該当のエラーなく動作するようになりました。 エラー自体が間欠的なものなのですが、今のところ丸一日問題なく動いているので多分大丈夫です。 ちょっと乱暴な対処ですが、原因がわかるまでこれで運用してみようと思います。 > ところで、何のプロセスをKillしようとしていますか? Killしようとしているのは主にvbsやExcelのVBAマクロ、InternetExplorer等のプロセスです。 これらが動作が遅すぎたりエラーが出たりして止まることがあるのでKillしています。 そういった不具合がないように都度各スクリプトやマクロの修正はしているのですが、それでも何かしらの原因で止まってしまうことがあるのでこのような仕様にしています。 Excelブックの保存は「xlBooks.Save()」とすると「追加情報:公開メンバー 'Save' は型 'Workbooks' に見つかりませんでした。」エラーが出るので「xlBooks(1).Save()」を入れています。 Workbooksのオブジェクトの仕様がよくわからないのですが、「System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks(1))」などと入れると「追加情報:インデックスが無効です。 (HRESULT からの例外:0x8002000B (DISP_E_BADINDEX))」が出てしまいます。
kenshirou

2019/08/07 05:52 編集

試してはいないのですが、例えば、「xlBooks(1).Save()」のところは Dim bk As Object = xlBooks(1) のようにブックオブジェクトのインスタンスを変数で受け、 bk.Save() としてから、xlBooks変数のCOM解放の前に上記変数bkのCOM解放を行う、というイメージです。 ところで、System.Runtime.InteropServices.Marshal.ReleaseComObjectより、System.Runtime.InteropServices.Marshal.FinalReleaseComObjectを使用した方が安全だと言われています。 私は以下のサイト等を参考に、FinalReleaseComObjectを使用しています。 https://seikousyahenomichi.com/exceledit/
ot2os

2019/08/09 07:26

ご教示いただいた方法で正常に動作しました。 継続して動作するかは引き続き検証してみます。 ありがとうございました。
guest

回答1

0

自己解決

kenshirouさんにいただいた情報を基にプロセスのkill部分を下記のようにtryで囲うことによって処置しました。
少々乱暴な方法ですが、数日経っても正常に動作しているようなのでひとまずこれで使ってみることにします。

ありがとうございました。

VB

1Try 2 If UBound(arg) = 0 Then 'ユーザ名指定なくプロセス終了 3 For Each p As System.Diagnostics.Process In ps 4 'プロセスを強制的に終了させる 5 p.Kill() 6 Next 7 ElseIf UBound(arg) = 1 Then 'ユーザ名指定でプロセス終了 8 '対象のユーザー名のみ強制終了 9 pkill_by_user(arg(1), ps) 10 End If 11Catch ex As Exception 12 Console.WriteLine("プロセス「" & tgt & "」が終了できません。") 13End Try

同じく、kenshirouさんにいただいた情報を基にExcelのマクロ実行後のブック保存と終了処理は下記のようにFinalReleaseComObjectにしました。
こちらも数日動作していますが問題ないようです。

VB

1'セーブフラグがあれば保存する 2If saveE Then 3 Dim bk As Object = xlBooks(1) 4 bk.Save() 5 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(bk) 6End If 7 8' Excel を終了する 9xlApp.Quit() 10System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlBooks) 11System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)

投稿2019/08/19 07:39

ot2os

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問