0

I want to develop C# Windows application managing Word documents. I want to recognize that another Word app is opening by another way (e.g. from Windows Start Menu) and I want to create warning about this.

The user can open the Word documents from main window of this application like this hardcoded test running on test button clicked:

myApp = new Word.Application();
Word.Document mydoc1 = myApp.Documents.Open("C://test/doc1.docx");
Word.Document mydoc2 = myApp.Documents.Open("C://test/doc2.docx");

The user can drag and drop texts or images from Treeview of main Window of this application to this opened documents (no problem).

But when the user opens new word app in a different way than by this application (for example, from the Start menu or double clicked WINWORD.EXE etc.), then working with this application is very confusing because drag and drop works correctly only on managed documents opened by this application.

I solve this by instruction for the user that “no other Word app must not be running” and the application will provide warnings about this situation.

I found, that checking at the application start is simple (something like this):

foreach (Process lP in Process.GetProcesses())
            {
                if (lP.ProcessName == "WINWORD")
                {
                    MessageBox.Show("Word is running, close please");
                    return;
                }
            }

But I don’t know how to recognize the situation that new another Word is opened afterwards when my app is already running. I think this checking will start periodically on some timer tick, but I don’t know how to recognize “my Word app” started by my app from the second “foreign Word app” started outside.

  • `but I don’t know how to recognize “my Word app” started by my app from the second “foreign Word app” started outside` Is that really needed? If you see two Word processes, then it means that another one has been started, right? – Kevin Gosse Apr 14 '19 at 09:51
  • Using UI Automation, adding an [AddAutomationEventHandler](https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.automation.addautomationeventhandler) with [WindowPattern.WindowOpenedEvent](https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.windowpattern.windowopenedevent), you'll be notified when any Windowed process (or Console) is run. An example [here](https://stackoverflow.com/a/55028688/7444103). The example includes means to close the new *Window*, should it be necessary. – Jimi Apr 14 '19 at 09:52
  • Kevin: ok, maybe it is so simple, I will try it with Word processes counting :) –  Apr 14 '19 at 10:05
  • Jimi: thanks, if process counting will be not successful, I will study your advice :) –  Apr 14 '19 at 10:08
  • If you *count* the active Processes, you have to poll `Process.GetProcessesByName()` (using what? a Timer?). Not a great solution, IMO. – Jimi Apr 14 '19 at 10:18
  • Jimi: do you see any problem with this not great but simple solution? Once 1 sec the program will call something like this: Process[] mps = Process.GetProcessesByName("WINWORD"); return mps.Length; –  Apr 14 '19 at 19:18
  • Well, you have a synchronous procedure that runs each second instead of an asynchronous one that runs, eventually, when needed. Also, you know you have to dispose of the list of processes you just created, right? So, add `mps.ToList().ForEach(p => p.Dispose());`. Otherwise, you'll carry over those handles forever (and memory usage increases 1Mb every 15 seconds, if you have at least one process in the list). – Jimi Apr 14 '19 at 20:13

1 Answers1

0

I accepted this solution:

On Timer tick this method runs:

{
            int s;
            Process[] mps = Process.GetProcessesByName(aName);
            s= mps.Length;
            mps.ToList().ForEach(p => p.Dispose());
            return s;
}

I think it is simple solution.

I respect it is not great solution :). (...sorry Jimi, but thanks for warning about memory, according to Google, you're right).

Does anyone see any hidden problem?