こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

ファイルを開く前に状況を確認したい。

こんにちわ。

VBで定期的にアップロードされてくるテキストファイルを処理するツールを作成しています。

Win2K環境で、クライアントからFTP転送であるテキストファイルが転送されてきます。

VBで作成中のツールでは1分おきにファイルの有無を確認しています。

当初はうまく動いていましたがたまにエラーが出るようになりました。

いろいろ状況を見ていますと、ファイル転送と同タイミングでファイルを開いた場合に起こっているようです。

FTP転送の有無にかかわらず、該当するファイルが自分自身のプログラム以外から開かれているということをチェックする方法はないですか?

開いていればスキップすると言う方法でこのエラーを回避したいのですが・・・。

お手数をお掛けいたしますが何卒お願い致します。

投稿日時 - 2005-09-12 17:42:55

QNo.1644625

暇なときに回答ください

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(11)

ANo.11

話が原点に戻りそうですが、、、、

#10さん
strSQL = "SELECT * FROM Win32_Process where name = 'ftp.exe'"
Wscript.Echo GetObject("winmgmts:").ExecQuery(strSQL).Count
ということをしたいのですか?
http://okweb.jp/kotaeru.php3?q=655810

私も先ほどの#8でのスクリプトのどこがWin2Kでのサポート外に該当するかわかりませんが、上記スクリプトは2K環境でも動きました。


しかし、、、
FTPでアプロード中に、サーバ側でftp.exeを起動しているとは限らないのではないですか?
質問者は
・サーバ側の$ftproot以下のファイルを監視する
・見つかったファイルが、受信中か完了かを知りたい(サーバ側で)
というのではないですか?

私が知っている限りですが[ftp.exe]は単なるクライアントアプリだと思うのですが、、、
サーバでは、受信をサービス(inetinfo.exe)が行っていると思っています。
http://www.geocities.co.jp/SiliconValley-SanJose/3220/XP-service.htm


なのでftp.exeが起動している確立があるのは、送信側のクライアントの方で、サーバ側は普通であれば立ち上がっていなく、仮に起動していても、それが受信中かどうかはわからないのでは?そうじゃなくても、ftp.exeではなくFFFTPなどのツールアプリで行っているかもしれないし、、、

#10さんの履歴を見るとASPでの回答が多いので、私の知らない'おまじない'があるのか、あるいは私の認識違いかと思って、疑問に思ったことを(便乗して)投げさせていただきました。
m(_ _)m

投稿日時 - 2005-09-13 15:32:45

ANo.10

>#8さん
>質問者はWin2Kのようですが、そのスクリプトは動作サポート外では?
こちらなのですが、OSの記載はありませんでした。
当方はXPでしか動作確認はできていないので、「自信なし」。
http://www.microsoft.com/japan/technet/scriptcenter/scripts/os/process/procthd/pcthvb07.mspx

投稿日時 - 2005-09-13 14:34:15

ANo.9

#8さん

質問者はWin2Kのようですが、そのスクリプトは動作サポート外では?
(違っていたらすいません)

http://www.microsoft.com/japan/technet/scriptcenter/scripts/os/process/procthd/pcthvb05.mspx

投稿日時 - 2005-09-13 13:22:19

ANo.8

1050YENさんのNo.7の方法で解決かも知れませんが、
一応、ftp.exeが動いているかのチェックを
スクリプトセンターにあったコードに判断を1つ加えてみました。

Set objDictionary = CreateObject("Scripting.Dictionary")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery _
("Select * from Win32_Process")
For each objProcess in colProcesses
objDictionary.Add objProcess.ProcessID, objProcess.Name
Next
Set colThreads = objWMIService.ExecQuery _
("Select * from Win32_Thread")
swFind = 0
For each objThread in colThreads
intProcessID = CInt(objThread.ProcessHandle)
strProcessName = objDictionary.Item(intProcessID)
If InStr(strProcessName, "ftp.exe") <> 0 Then
swFind = 1
Wscript.Echo strProcessName & VbTab & objThread.ProcessHandle & _
VbTab & objThread.Handle & VbTab & objThread.ThreadState
Exit For
End If
Next
If swFind <> 1 Then Wscript.Echo "FTP Not Running!"

投稿日時 - 2005-09-13 13:17:04

ANo.7

検証してみました。

WinXPSp2にて、IISのFTPサーバを立ち上げ、FTPコマンドで大きいファイルのアップロードを行い、先に挙げた参考URLのIsNoOpen関数を利用しました。
(1)For Binary Lock Read As #1
(2)For Binary Lock Read Write As #1
どちらでも、アップロード中を認識できました。


これまた以前に言いましたが、FTP側ではどうやら
※FTP受信処理
{
 ファイルオープン(新規モード)
  {
   受信終了まで書き込み
  }
 ファイルクローズ
}
という処理を行っているようです。(検証結果からの考察)


ちなみに、ファイルをFTPがロックしていようといまいと、FTPがオープンしているだけで、他から排他で開くことができないので、意識する必要はありません。

投稿日時 - 2005-09-13 12:16:21

ANo.6

>チェックを行うVB側の方の処理を書いたのですよー
考えてみれば、先行Openする方がLockしてくれないと
VB側ではこの方法では検知不可能ですね。

> FTP接続が実行中だとかいう情報をAPIなどから...
タスクマネージャを動かしておいて、コマンドプロンプトで
FTPを起動させると、プロセスに「ftp.exe」が起動されますから、これを確認すれば良いと思います。
参考URLはプロセス関係のスクリプト集です。

参考URL:http://www.microsoft.com/japan/technet/scriptcenter/scripts/os/process/default.mspx

投稿日時 - 2005-09-13 09:16:14

ANo.5

>#3さんの、
>>>Open inXlsFileName For Binary Lock Read Write As #1
>>となっていますが、Writeはきっといらないですね^^;
>は、逆でしょう。

いえ、FTP側はVBではなさそうなので、チェックを行うVB側の方の処理を書いたのですよー

投稿日時 - 2005-09-13 00:04:31

ANo.4

#3さんの、
>>Open inXlsFileName For Binary Lock Read Write As #1
>となっていますが、Writeはきっといらないですね^^;
は、逆でしょう。
こちらの思惑では、FTPがWriteロックしてくれていれば、
Lock Writeによって読み出しがエラーになるので、
「まだ出力中かも知れない」と判別がつくのです。

FTPの方はファイルをロックしてくれていないのでしょうか。

投稿日時 - 2005-09-12 22:46:31

補足

皆さん、いろいろコメントを有難う御座います。

まず、FTPサーバー機能はWin2kの標準機能を採用しています。
各クライアントからのFTPソフトは何か決まっていませんのでどのような方法でファイルをアップロードしているかは特定出来ません。

アップロードしている最中であるとか、FTP接続が実行中だとかいう情報をAPIなどから取得する他ないのでしょうか??

投稿日時 - 2005-09-12 23:13:04

ANo.3

追記です。

#2の参考URLは
>Open inXlsFileName For Binary Lock Read Write As #1
となっていますが、Writeはきっといらないですね^^;

投稿日時 - 2005-09-12 19:02:33

ANo.2

>Open Filename For Input As #fileNo

#1さんが言われている
>Lock Read Write
ですが、
http://okweb.jp/kotaeru.php3?q=611232
にて「IsNoOpen」の命名で関数化されています。


※FTP受信処理
{
 ファイルオープン(新規モード)
  {
   受信終了まで書き込み
  }
 ファイルクローズ
}
という感じで、FTP側が処理をしていたら、この方法で回避できると思います。



もし↓のような2部構成になっていた場合は、回避しようがありませんので、別方法を考える必要があるかもしれません。
※FTP受信処理パート1
{
 ファイルオープン(新規モード)
 受信データを書き込み
 ファイルクローズ
}
※FTP受信処理パート2
{
 ファイルオープン(追加モード)
 受信データを書き込み
 ファイルクローズ
}

投稿日時 - 2005-09-12 19:00:30

ANo.1

テキストファイルの処理はどのような記述でしょうか。
OpenステートメントならLock Read WriteとOn Errorステートメントの併用で
チェックできると思います。

FSOのOpenTextFileだと読み取り専用で開いてしまうので
Lock指定はできないようです。

投稿日時 - 2005-09-12 17:55:51

補足

アドバイス有難う御座います。

ファイルにアクセスしているタイミングは2回あります。
まず1回目がファイルの有無を確認しています。
2回目がファイルがあった場合に読み出しをしています。

1回目の有無確認は次のようにしています。

If Dir(Filename, vbNormal Or vbSystem Or vbReadOnly Or vbArchive Or vbHidden) = "" Then
'存在しない
List2.AddItem Date & "-" & Time & vbTab & List3.Text & vbTab & vbTab & "存在しない"
OkFLG = 0
Else
'存在する
List2.AddItem Date & "-" & Time & vbTab & List3.Text & vbTab & vbTab & "存在する"
OkFLG = 1
End If

次に、読み込みは、

'ファイルを開きます。
Open Filename For Input As #fileNo

と普通に開いています。

但し、FTPサーバーはどのような方法で開いているか分かりません。

宜しくお願い致します。

投稿日時 - 2005-09-12 18:41:26

あなたにオススメの質問