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

監視フォルダにWordが入ったときにそのWordを起動したい

環境/言語:[C#,VisualStudio2013Pro]
分類:[.NET]


いつも拝見させていただいてます。

表題のとおり、
監視していたフォルダにWordを確認したときにそのWordを
起動する処理をしたいと考えています。

監視処理は
FileSystemWatcherを利用して監視しています。

@ private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + " ファイル 「" + e.FullPath + "」が変更されました。");
}

A private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + " ファイル 「" + e.FullPath + "」が作成されました。");
}

B private void fileSystemWatcher1_Deleted(object sender, System.IO.FileSystemEventArgs e)
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + " ファイル 「" + e.FullPath + "」が削除されました。");
}

C private void fileSystemWatcher1_Renamed(object sender, System.IO.RenamedEventArgs e)
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + " ファイル 「" + e.OldFullPath + "」から「" + e.FullPath + "」に名前が変更されました。");
}


今はリストボックスに監視結果が出るようにしています。
これをAのfileSystemWatcher1_Createdで新規作成を確認できたら
下記の要件を満たしたいと思っています。

1.label1にファイル名が入るようにしたい。
2.その後Wordを起動したい。
  (編集中の待機の処理の仕方は必要?)
3.保存されたことを知れるようにしたい。

テキストファイルとWordファイルの起動の仕方が違うと考えていて、
色々参考サイトを探しましたが、これだ!というものが見つかりません。


もし、よろしければ
要件についての処理、もしくは、参考サイトを教えていただけないでしょうか?

よろしくお願いいたします。
■No32669に返信(k-kさんの記事)

まずはじめに何が分からないのかがよく分からないのですが、
> 要件についての処理、もしくは、参考サイトを教えていただけないでしょうか?
ということなので
要件1、2、3がすべて分からないということではないですよね?
(全体的に読むと要件2だけが分からないようにも受け取れますが、
 最終的には要件の部分がすべて分からないと言っているように受け取れるので。)



> 1.label1にファイル名が入るようにしたい。

ただ書かれた内容をそのまま対処すると以下のようになります。

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
    label1.Text = e.FullPath;
}

しかし、ListBoxへ出力できているのですが、そういう意味ではなく
> 1.label1に[パスがない状態の]ファイル名[だけの文字列]が入るようにしたい。
という意味であれば以下のようにすればよいかと思います。

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
    label1.Text = e.Name;
}

> 2.その後Wordを起動したい。
>   (編集中の待機の処理の仕方は必要?)

これも、ただ書かれた内容をそのまま対処すると以下のようになります。

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
    System.Diagnostics.Process.Start("C:\〜インストールされたパス〜\WINWORD.EXE");
}

しかし、これも前後の意味として考えると不明なので、そういう意味ではなく
> 2.その後[作成を検知した]Word[ファイル]を起動したい。
という意味であれば以下のようにすればよいかと思います。

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
    System.Diagnostics.Process.Start(e.FullPath);
}

参考
http://dobon.net/vb/dotnet/process/shell.html

#一般的にWordで作成されたファイルのことは「Word」とは言わず、
#「Wordドキュメント」、「Wordファイル」、「Docファイル」などといいます。
#逆に「Word」というとMicrosoftが提供している実行体(EXE)の事等を指します。


> 3.保存されたことを知れるようにしたい。

ListBoxへ出力できているのですから、ある意味知れるようにはなっていますよね?
そういう意味ではなく他の意味かと考えましたが、ここについてはよくわかりませんでした。
(新規作成されたという事は保存された訳ですから。
 新規作成された後に保存という意味???)

もう少し的確な説明をして頂けたらと思います。(全般的に)
■No32670に返信(anさんの記事)
> ■No32669に返信(k-kさんの記事)
ご返信ありがとうございます。

説明の1つ1つが曖昧だったと反省しています。
申し訳ありません。


> 要件1、2、3がすべて分からないということではないですよね?
> (全体的に読むと要件2だけが分からないようにも受け取れますが、
>  最終的には要件の部分がすべて分からないと言っているように受け取れるので。)

おっしゃる通り、label1でのファイル名の出力は済んでおります。
本題とは関係のないことが急に出てきて困惑されるのも無理ないかと思います。
2の「Wordファイル」の起動の仕方が分からなくて困っていました。

また、その先の3も少しお聞き出来たら、と思いました。


>>2.その後[作成を検知した]Word[ファイル]を起動したい。
> という意味であれば以下のようにすればよいかと思います。
>
> private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
> {
> System.Diagnostics.Process.Start(e.FullPath);
> }

ありがとうございます。上記の処理でうまくいきそうです。


> #一般的にWordで作成されたファイルのことは「Word」とは言わず、
> #「Wordドキュメント」、「Wordファイル」、「Docファイル」などといいます。
> #逆に「Word」というとMicrosoftが提供している実行体(EXE)の事等を指します。
 
このご指摘もありがとうございました。
今まで「Word」を意識していませんでした。
一番の驚きでした。
勉強になります。




>>3.保存されたことを知れるようにしたい。
>
> ListBoxへ出力できているのですから、ある意味知れるようにはなっていますよね?
> そういう意味ではなく他の意味かと考えましたが、ここについてはよくわかりませんでした。
> (新規作成されたという事は保存された訳ですから。
>  新規作成された後に保存という意味???)

こちらは「Wordファイル」保存された場合は≪備考≫を入力するフォームを出そうとしていました。
そのため、「Wordファイル」が保存(更新)された時を知る方法を
お聞きしたかったのです。


説明下手で申し訳ありません。
■No32672に返信(k-kさんの記事)
> そのため、「Wordファイル」が保存(更新)された時を知る方法を
> お聞きしたかったのです。

それだと、FileSystemWatcher の役目では無いですね。

Word.Application オブジェクトの DocumentBeforeSave イベントを
使ってみては如何でしょうか。プログラムから Word を起動するのであれば
参照設定するだけで、比較的簡単に取り扱うことが出来ます。


自身で呼び出したWord のインスタンスではなく、別途起動された Word も
監視したいのであれば、GetRunningObjectTable API 経由で
実行中の Word.Application オブジェクトを列挙できます。

使えないでしょうか。

起動済みの Application インスタンスは、
■No32672に返信(k-kさんの記事)

> ありがとうございます。上記の処理でうまくいきそうです。

それはよかったです。


> こちらは「Wordファイル」保存された場合は≪備考≫を入力するフォームを出そうとしていました。
> そのため、「Wordファイル」が保存(更新)された時を知る方法を
> お聞きしたかったのです。

単純に「保存(更新)」という意味であれば、
Changedイベントにて処理を書けば良いという風に感じます。

しかし、当初
>>> これをAのfileSystemWatcher1_Createdで新規作成を確認できたら
>>> 下記の要件を満たしたいと思っています。
と、「Createdで〜」と仰っているので、
Createdイベント中での処理という意味なのかと思い込んでいましたが、
そういう意味ではないという事でしょうか?
(要件1、2についてはCreatedイベント中での処理ということもあり。)

#日本語ムツカシイ^^;


一旦上記のような思い込みを忘れて、
今までの話を総合的に深読みしてみましたが、
やりたい内容の概要としては、以下のようなことでしょうか?
 ・新規作成として認識できたファイルにおいて、
  同じファイルが更新されたと認識された場合のみ処理したい。
 ・新規作成として認識できていないファイル(元から存在していたファイル)においては、 
  更新されても無視したい(何もしない)。
 ・新規作成として認識できたファイルにおいても、
  一度更新されたと認識されて処理済のファイルについては、無視したい(2度は処理しない)。
魔界の仮面弁士さん
ご返信ありがとうございます。


>それだと、FileSystemWatcher の役目では無いですね。

>Word.Application オブジェクトの DocumentBeforeSave イベントを
>使ってみては如何でしょうか。プログラムから Word を起動するのであれば
>参照設定するだけで、比較的簡単に取り扱うことが出来ます。

DocumentBeforeSaveイベントですか。
調べてみます。
ありがとうございます。


>自身で呼び出したWord のインスタンスではなく、別途起動された Word も
>監視したいのであれば、GetRunningObjectTable API 経由で
>実行中の Word.Application オブジェクトを列挙できます。

>使えないでしょうか。

>起動済みの Application インスタンスは、

ありがとうございます。
こちらも調べてみたいと思います。






anさん
ご返信ありがとうございます。

> しかし、当初
> >>> これをAのfileSystemWatcher1_Createdで新規作成を確認できたら
> >>> 下記の要件を満たしたいと思っています。
> と、「Createdで〜」と仰っているので、
> Createdイベント中での処理という意味なのかと思い込んでいましたが、
> そういう意味ではないという事でしょうか?
> (要件1、2についてはCreatedイベント中での処理ということもあり。)

AのCreatedイベントで確認されたWordファイルの起動
そして、Changedイベントで変更を確認する。

anさんのお考え通りとは異なり、
CreatedはWordファイルを確認し、Wordファイルの起動をする「だけ」
Changedはその変更を確認する「だけ」

このように2つに分けてと考えておりました。

またしても混乱させてしまう書き方だったこと、
本当に申し訳ありません。
日本語が不十分なのは、私の方です。

(お恥ずかしい。。。)


> 一旦上記のような思い込みを忘れて、
> 今までの話を総合的に深読みしてみましたが、
> やりたい内容の概要としては、以下のようなことでしょうか?
>  ・新規作成として認識できたファイルにおいて、
>   同じファイルが更新されたと認識された場合のみ処理したい。

そのとおりです。
基本的には「Word」のみで考えております。


>  ・新規作成として認識できていないファイル(元から存在していたファイル)においては、 
>   更新されても無視したい(何もしない)。

そのとおりです。
元から存在しているファイルに関しては、後から更新されても無視したいです。
また、消去も考えておりません。
おっしゃる通り、「何もしない」が正しいかと。


>  ・新規作成として認識できたファイルにおいても、
>   一度更新されたと認識されて処理済のファイルについては、無視したい(2度は処理しない)。
>

ここは私もよくわかっていないのですが、
2度処理はしない、という点については合意です。

更新の考え方ですが、
起動時にタイムスタンプを保持しておき
終了時にタイムスタンプを保持、
それを比較し、差異がある場合は「更新」するべきである。
と認識したいと考えております。



(あぁ…ダメだ。私の日本語力では限界が…。)
■No32675に返信(k-kさんの記事)

だいたいやりたい事が理解できました。

> 更新の考え方ですが、
> 起動時にタイムスタンプを保持しておき
> 終了時にタイムスタンプを保持、
> それを比較し、差異がある場合は「更新」するべきである。
> と認識したいと考えております。

「終了時」というのをどう受け取るかにもよりますが、
自分が提示した
System.Diagnostics.Process.Start(e.FullPath);
のやり方を使用するのであれば、
Startメソッドの戻り値よりプロセスが取得できると思いますので、
そのプロセスが終了するまで待機することになると思います。

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
    MessageBox.Show("ここで現在のファイルの更新日時を取得処理を記述");
    label1.Text = e.Name;
    System.Diagnostics.Process p =  System.Diagnostics.Process.Start(e.FullPath);
    p.WaitForExit();
    MessageBox.Show("ここに更新されてるかチェック処理と更新されている場合の処理を記述");
}

参考:http://dobon.net/vb/dotnet/process/openfile.html



蛇足ですが、
この場合、この処理が終わるまで自身のプログラムが応答なし状態になると思います。
ちなみにこの状態は次のファイルが来ても処理してくれません。
応答なし状態を回避したければ、以下も参照してみてください。

参考:http://dobon.net/vb/dotnet/programing/progressdialogbw.html
■No32677に返信(anさんの記事)
> ■No32675に返信(k-kさんの記事)

anさん
ご返信ありがとうございます。


いただいた全部のアドバイスをもとに頑張ってみようかと思います。
拙い説明でも親身にご意見くださり、本当にありがとうございます。


また、後日、
自分の処理をまとめてここに載せたいと思います。


おそらく残り少々だと思いますので解決済みにいたします。

anさん
魔界の仮面弁士さん

本当に助かりました。
今後もよろしくお願いいたします。
解決済み!

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