3

I have this superb awesome WPF application where users, among several other things, upload files that then are stored in a database (requirement). At anytime a user running this application can click on a file hyperlink to open the file at his local computer. In order to do this I simply use:

var process = Process.Start(tempPath);

I deserialize the bytes stored in database and write a temp file on an specific folder. Another requirement was that if the user performs any changes to the temp file, he can simply click save in whatever application is using and the file then should be automatically saved to the database. I use FileSystemWatcher to know if the temp file was modified and the following to keep track of the process:

await process.WaitForExitAsync(async () =>
{
    if(!wasModified) return;

    this.SetBusy();
    var path = _workDocumentsOpened[work.Id];
    _workDocumentsOpened.Remove(work.Id);
    await work.SetDocumentAsync(path, work.DocumentFileName);
    File.Delete(path);
    this.SetNotBusy();
});

This works fine most of the time. However since there is no restriction in the type of file (extension) that the user can upload, if a user downloads the file and does not have a default application configured for it then the following Windows dialog is shown:

enter image description here

The problem is that by that time Process.Start returned null =( and so far I have not been able to figure out how to detect which process is selected by the user to open the file or if the operation is simply cancelled.

Any help is appreciated

taquion
  • 2,667
  • 2
  • 18
  • 29
  • You could use some of the classes in AutomationElement to detect the How do you want to open this file? window. – Ryan Wilson Jun 07 '18 at 16:06
  • @RyanWilson, thanks, in order to do that I would need a handle to OpenWith.exe process, I do not want to automate the application selection, I rather want to wait for the user to pick an app. Besides if no app is found the automation will not work anyway – taquion Jun 07 '18 at 16:17
  • 1
    The docs for Process Startinfo say _"The file name is any application or document. Here **a document is defined to be any file type that has an open or default action associated with it.**"_. I'm not sure you'll be able to work round this, but you could [check in advance if there is an associated program](https://stackoverflow.com/a/1851579/43846) and warn the user that change tracking won't be enabled the first time they open a file that doesn't have an associated program. – stuartd Jun 07 '18 at 16:49
  • 1
    @taquion You could always get the collection of running processes before the call to Process.Start, and keep checking for new processes for x amount of time, I know not ideal, but possible solution. You may be able to map the file type to possible applications, then if a new process starts that maps to that file extension, you could almost assume that that is what the user used to open the file. – Ryan Wilson Jun 07 '18 at 16:51
  • 1
    Automation is not a bad idea. With `Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, (...)` you are notified when an application starts and you'll have its ProcessID, Window Title etc. But, you could verify yourself beforehand if a file association exists and propose, in case of a missing association, to open the file with some application, as a substitute for the Windows default action applet. So you will control the whole operation. – Jimi Jun 07 '18 at 16:59
  • Thanks @stuartd, I already notify the user if a default application is not set. – taquion Jun 07 '18 at 17:01
  • @RyanWilson following your comment, I am able now to wait for process OpenWith.exe to start and to exit. I still do not know how to know which process was selected. I will try Jimi and your idea.. thanks – taquion Jun 07 '18 at 17:02
  • 1
    @taquion You're welcome. Good luck, keep us posted on your progress. I have written an entire library that helps wrap the Automation stuff, which I would be happy to provide. – Ryan Wilson Jun 07 '18 at 17:04
  • 1
    Also, you could combine the operation you choose, by checking the application that, eventually, has opened the file you're watching. One way is in this SO answer: [How do I find out which process is locking a file](https://stackoverflow.com/questions/317071/how-do-i-find-out-which-process-is-locking-a-file-using-net) (not the accepted answer). – Jimi Jun 07 '18 at 17:15
  • Thanks! I think that with all this stuff combined I can manage to solve it. I will post the answer when I came with the solution. @RyanWilson I will let you know if I need that library! =) – taquion Jun 07 '18 at 17:33
  • @taquion Sounds good. Happy coding :) – Ryan Wilson Jun 07 '18 at 17:46

0 Answers0