常駐型の市販ソフトによるファイル操作の干渉

タグの編集
投稿者 ひでと  (社会人) 投稿日時 2015/1/13 16:08:13
おせわになります。
VB2005にていくつか自作のプログラムを使用しています。
その中でテキストファイルを作ったり、読み込んだりの処理がありますが、
最近、市販の常駐型ソフト(セキュリティーとディスクデフラグのソフト)に干渉を受けているようです。

実行中にファイルのアクセスが出来ないというエラーがたまにあります。
そのとき、上記の市販のソフトが活動している表示があります。
想像するに、たまたま同じファイルをアクセスしていてエラーになっているのかと思います。

ファイルの読み書きのときにこういったエラーを回避する処理をご教示御願いします。
投稿者 shu  (社会人) 投稿日時 2015/1/13 16:37:08
try~catch
で例外をとらえ、catchされたときは
待ちを入れて再実行とか。
投稿者 るきお  (社会人) 投稿日時 2015/1/14 22:23:53
こっちでファイルをつかんだら処理が終わるまで離さないようにすることになると思います。

具体的にはひでとさんがどうやってファイルにアクセスしているのかによりますが、
たとえば、File.Openを使ってファイルを開いている場合は、FileShare.Noneを指定するとファイルを排他的につかんで他のプロセスからのアクセスを排除することができます。
この状態だと、別のソフトでそのファイルを開くことはできず、エクスプローラを使ったコピーすらできなくなります。
ですから、ひでとさんが干渉を受けているというソフトも干渉できなくなるでしょう。
もちろん、処理が完了してファイルを閉じれば他のソフトからもアクセスできるようになります。

この機能を使ったWindowsフォームのサンプルを紹介します。
Button1をクリックするとC:\vb\myfile.txtを開きます。Button2をクリックすると日付を書き込みます。Button3をクリックするとファイルを解放します。
Button1をクリックしてから、Button3をクリックするまでの間他のソフトはこのファイルにアクセスできなくなります。

Public Class Form1

    Dim stream As IO.Stream
    Dim writer As IO.StreamWriter
   
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim fileName As String = "C:\vb\myfile.txt"
        stream = IO.File.Open(fileName, IO.FileMode.Create, IO.FileAccess.ReadWrite, IO.FileShare.None)
        writer = New IO.StreamWriter(stream)

    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        writer.WriteLine(Now.ToString)

    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        writer.Close()
        writer.Dispose()

        stream.Close()
        stream.Dispose()

    End Sub
End Class


なお、File.Openを使うのが解決策だというわけではなく、ひでとさんがどうやっているかによって回答が変わるという話だけだと意味がわからないかと思って一例を載せただけです。

こういうことではなく、そもそもファイルをつかむことすらできない状態なら shuさんのおっしゃるようにTry Catch等で辛抱するしかないですのですが、「ファイルを作ったり」と書いたあったので、作る瞬間は確実につかめるはずですから、上記のような解決策も可能性はあるなと思いました。
投稿者 ひでと  (社会人) 投稿日時 2015/1/16 10:50:18
shu様、るきお様、ありがとうございます。

ほとんどの場合、エラーは書き込みの場合に出ているようです。

通常単純に下のように扱っています。
 Dim JFile As IO.StreamWriter
 JFile = New IO.StreamWriter(TEMP_TXT, True, System.Text.Encoding.Default)
 With JFile
  .WriteLine("lc3")
  '処理
End With
JFile.Close()

比較的小さなプログラムが数多いの(100以上有り)で、修正が少なくすむ方法がありがたいです。
shu様に教えて頂いた方法を使うのに、
try文を使ってGoto文を考えましたが、良くないですよね。
待ちと再実行のうまい方法を教えていただけたら助かります。

るきお様の教えていただいた方法も利用できるかも知れません。
StreamWriterで使用できるかも調べてみないといけませんね。

困っているのは、再現性の問題もありまして。
市販のソフトに影響されていると思われるので、たまたまの機会にしか現れないのです。
修正してもうまくできているか確認がとれないのが悩ましいです。



投稿者 shu  (社会人) 投稿日時 2015/1/16 22:34:01
一例ですが
以下のような処理方法があります。

For Cnt = 1 To 5
    Try
        ~ 処理 ~
        Exit For
    Catch
        ~ 例外対応処理 ~
        待ち
    Finally
        資源の解放
    End Try
Next
If 上記ループが成功 Then
    ~ 成功したときの処理 ~
Else
    ~ 失敗したときの処理 ~
End If
投稿者 ひでと  (社会人) 投稿日時 2015/1/19 10:00:05
shu様

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