2010-12-16 8 views
0

スクリーンショットを取得してファイルに保存し、そのファイルでPaint.NETを開き、Paint.NETでファイルの編集が完了したら編集したファイルをサービスにアップロードします。Paint.NETでファイルの編集が完了したらどうすればいいですか?

私は他のものをカバーしています。 Paint.NETで画像の編集が完了したら、どうすれば検出できますか?

私は.NET 3.5、C#を使用しています。

FileSystemWatcherを使用して、特定のファイルの変更を検出できます。しかし、ファイルが最初に変更されても必ずPaint.NETが終了したとは限りません。私はPaint.NETが終了するのを待つことができます - 私は、Windowsのプロセスのリストを調べ、Paint.NETがなくなったことを検出すると思います。しかし、ユーザーは実際にPaint.NETを閉じることなくファイルの編集を終了することができます。

Paint.NETを閉じるようにユーザーに指示する必要がある場合、ファイルのアップロード準備ができていることを知らせるために、私はそれを行うことができると思います。しかし、私はそのような余分な要件を避けることを望んでいます。

編集中のファイルをPaint.NETで開いている場合は、、つまりを見てみるといいでしょう。しかしどうですか?おそらくポーリングによって、FileShare.Noneでファイルを開こうとしています。

良い方法がありますか?


EDIT - いいえ、Paint.NETがいなくても読書のために、開いているファイルを保持しません。 Paint.NETによって表示/編集されている間でも、FileShare.Noneで問題なく画像ファイルを開くことができます。そのアイデアはうまくいきません。


Paint.NETには、開いているファイルを調べるためのRemotingインターフェイスがありますか?それは私の目的に合ったものです。

答えて

0

これをちょっと試してみたら、UIオートメーションが満足すると思います。 .NET 3.0で新しく追加されたSystem.Windows.Automationクラスを使用すると、マシン上の他のWindowsの内容について問い合わせることができ、特定のプロセスIDのウィンドウを見つけることができます。だから、

  • のPaintDotNetを見つけることです。そのウィンドウの"name" propertyをチェックPaintDotNetアプリ
  • のメインウィンドウのAutomationElementを取得System.Diagnostics.Process.GetProcesses
  • で検索を経由してexeファイルのプロセス。
  • "myfile.jpg"から何かに変更された場合、Paint.NETは ファイルの編集を中止しています。
  • ElementNotAvailableExceptionを取得した場合、Paint.NETが終了したことを意味します。

私は非常にこれをテストしていませんが、しかし、このコードは私の目的のために働くようだ:

public void Run() 
{ 
    var shortFileName = Path.GetFileName(_filename); 
    System.Console.WriteLine("Waiting for PDN to finish with {0}", shortFileName); 

    var s= from p in Process.GetProcesses() 
     where p.ProcessName.Contains("PaintDotNet.exe") 
     select p; 

    if (s.Count()==0) 
    { 
     System.Console.WriteLine("PDN is not running."); 
     return; 
    } 

    var process = s.First(); 
    var window = AutomationElement.RootElement.FindChildByProcessId(process.Id); 

    string name = 
     window.GetCurrentPropertyValue(AutomationElement.NameProperty) as string; 

    if (!name.StartsWith(shortFileName)) 
    { 
     System.Console.WriteLine("PDN appears to NOT be editing the file."); 
    } 
    else 
    { 
     try 
     { 
      int cycles = 0; 
      do 
      { 
       System.Threading.Thread.Sleep(800); 
       name = window.GetCurrentPropertyValue(AutomationElement.NameProperty) as string; 
       if (!name.StartsWith(shortFileName)) break; 
       cycles++; 
       System.Console.Write("."); 
      } while (cycles < 24); 

      if (!name.StartsWith(shortFileName)) 
       System.Console.WriteLine("PDN is done."); 
      else 
       System.Console.WriteLine("Timeout."); 
     } 
     catch (ElementNotAvailableException) 
     { 
      System.Console.WriteLine("PDN has exited."); 
     } 
    } 
} 

FindChildByProcessId方法はthis blog postから拡張メソッドです。それは次のようになります。

public static class AutomationExtensions 
{ 
    public static AutomationElement FindChildByProcessId(this AutomationElement element, int pid) 
    { 
     var cond = new PropertyCondition(AutomationElement.ProcessIdProperty, pid); 
     var result = element.FindChildByCondition(cond); 
     return result; 
    } 

    public static AutomationElement FindChildByCondition(this AutomationElement element, Condition cond) 
    { 
     var result = element.FindFirst(TreeScope.Children, cond); 
     return result; 
    } 
} 

これは少し異例のようだが、それだけで動作します。最も難しいのはタイミングです。アプリを起動させるのに十分長く待つ必要があります.1秒か7秒です。それから、UIAutomationクラスでそれに接続しようとします。

0

残念ながら、いい方法はありません。 Microsoft Outlookのようなアプリケーションでは、添付ファイルを編集するときに同じ問題が発生します。上記のすべてのアプローチを取ることで、最高の推測の努力をすることができます。

たとえば、Paint.NET(または関連するエディタ)にシェルした後にアプリケーションが再度アクティブになったときに、ファイルが変更されているかどうかを確認し、完了したらプロンプトを表示することができます。プロセスが終了した場合は、完了したことを示すかなりの兆候として使用することができ、プロンプトをスキップします。ファイルシステムウォッチャーが変更を検出した場合、Paint.NETがアクティブでなくなるまでそれらのファイルをキューに入れることができます。

多くのアプリケーションは、ファイルの編集中にロックを保持しません。私はかなりPaint.NETはしていないと確信しています。 OfficeのようなアプリケーションはOutlookからのWord/Excel添付ファイルの編集がプレーンテキストファイルよりもずっと信頼性の高い理由です。

関連する問題