none
How to open word document and block a rest of the code until user exit word ? RRS feed

  • Question

  • Hi

    i've used this code to open the word document, then block the rest of code until the user close the word app :

    ProcessStartInfo psi = new ProcessStartInfo(fullPath);
    Process p = Process.Start(psi);
    
    if (p == null)
    {
    	// Word is already running, and handled the file above...
    	p = Process.GetProcessesByName("WINWORD")[0];
    }
    
    if (p == null)
    {
    	// Handle error case...
    	// ie: Word may not be installed, or something else is handling this file...
    }
    
    p.WaitForExit(); // This line was blocked, until the user exit word app!
    p.Close();
    
    // load new order and save to datarow
    byte[] changedDocument = Utilities.ReadDocument2ByteArray(fullPath);

    The above code works for word 2007, but in 2013 (or maybe higher), this line does not block :

    p.WaitForExit();

    Can anybody help me how to solve this problem ?

    thanks in advance.


    http://www.codeproject.com/KB/codegen/DatabaseHelper.aspx

    Wednesday, January 23, 2019 7:07 PM

Answers

  • So you're trying to mix Word COM with the Word App? Probably not going to work out well. When you load Word via COM then it'll stay loaded until you stop using it AND then it will remain loaded by Windows for a while thereafter (in case you need it again). So if you're simply looking for a "Word" process then it could be the COM object which means it'll be around a while. You don't really want to mix the 2 or at least rely on the process going away.

    Once you're WriteInfoToWordDoc method is done with the app it needs to clean it up so call the Quit method. With the call to Quit I see the process exit after about 1 minute.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Hamed_1983 Friday, January 25, 2019 4:39 PM
    Friday, January 25, 2019 4:27 PM
    Moderator

All replies

  • Hi Hamed_1983,

    Thank you for posting here.

    For your question, I test on my computer. But I only have Word 2016, I get the same situation as yours. This line p.WaitForExit() would not blocked until the user exit word app. Sorry for that, I do not have, I do not have the Word 2007 to test.

    Maybe the situation is only for word 2007. If it is possible, could you use the word 2007 instesd of word 2013 or higher version. 

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 25, 2019 6:41 AM
    Moderator
  • You're code doesn't look correct to me. I assume fullPath is the name of a Word document and not the word process itself correct? You start the process and then check to see if the process that was started is null. It'll never be null so it doesn't execute the GetProcessesByName functionality.

    With Word 2016 this code correctly blocks. But as I already said you're blocking on the Process.Start result, not Word. If you didn't have the if check then it would try to find the first Word process but note that it may not exist so your code would throw an exception because you assume it does and you grab the first one. If the user already has Word open then your code will potentially block on the wrong file. Here's updated code to try.

    class Program
    {
        static void Main ( string[] args )
        {
            var fullPath = @"C:\Temp\temp.docx";
    
            var psi = new ProcessStartInfo(fullPath);
    
            var p = Process.Start(psi);
            Console.WriteLine($"Started process {p.Id}");
            if (p == null)
            {
                Console.WriteLine("Should never get here");
                p = Process.GetProcessesByName("Winword").FirstOrDefault();
            };
    
            if (p == null)
            {
                Console.WriteLine("Word not found");
            } else
            {
                Console.WriteLine($"Waiting for process {p.Id} to exit");
                p.WaitForExit();
    
                Console.WriteLine("Exited");
                p.Close();
            };
                
        }
    }

    At least on newer versions of Word be aware that just because the UI goes away doesn't mean the process terminates. On my machine there is an almost minute delay before Word (the process) terminates. During this time your app is blocked.


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, January 25, 2019 3:07 PM
    Moderator
  • Hi again.
    I've found the problem!
    The 'p.WaitForExit' method works correctly if i don't use 'WriteInfoToWordDoc'. in 'WriteInfoToWordDoc' method, i've
    use the word object model to perform some replacement(s) in my word file!
    Here is my whole code :

    if(Utilities.SaveFile(fullPath, templateRow.TemplateContent))
    {
    	List<DataRow> informationRows = new List<DataRow>();
    	informationRows.Add(this._patientRow);
    	if (WriteInfoToWordDoc(fullPath, informationRows)) // Cause the problem
    	{
    		ProcessStartInfo psi = new ProcessStartInfo(fullPath);
                    Process p = new Process();
                    p.StartInfo = psi;
                    p.Start();
                    
    		if (p == null)
                    {
                    	// Word is already running, and handled the file above...
                            p = Process.GetProcessesByName("WINWORD")[0];
                    }
    
    		if (p == null)
                    {
                    	// Handle error case...
                            // ie: Word may not be installed, or something else is handling this file...
                    }                                                              
    		
                    p.WaitForExit();
    
    		// The rest of my code ...
    	}
    }

    As u see in above code, if i remove this line of code (WriteInfoToWordDoc method), it works correctly!!
    Now my problem is that why this happen and how to solve this issue ?
    Here is the body of 'WriteInfoToWordDoc' method :

    public static bool WriteInfoToWordDoc(object fileName, List<DataRow> rows)
    {
    	bool result = false;
            object missing = System.Reflection.Missing.Value;
            object readOnly = false;
            object isVisible = false;
            object saveChanges = true;
    
    	// setup Word.Application class.
            Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
    
            // setup Word.Document class we'll use
            Microsoft.Office.Interop.Word.Document wordDoc = null;     
    
    	// set word to be not visible
            wordApp.Visible = false;
    
    	// open the word document
            wordDoc = wordApp.Documents.Open(ref fileName, ref missing, ref readOnly, ref missing, ref missing,
                        ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref isVisible, ref missing,
                        ref missing, ref missing);
    
    	// activate the document
            wordDoc.Activate();
    
    	// Insert some replacement(s) ...
    
    	wordApp.Documents.Close(ref saveChanges, ref missing, ref missing); 
    	result = true;
    
    	return result;
    }

    Thanks in advance.


    http://www.codeproject.com/KB/codegen/DatabaseHelper.aspx

    Friday, January 25, 2019 4:06 PM
  • So you're trying to mix Word COM with the Word App? Probably not going to work out well. When you load Word via COM then it'll stay loaded until you stop using it AND then it will remain loaded by Windows for a while thereafter (in case you need it again). So if you're simply looking for a "Word" process then it could be the COM object which means it'll be around a while. You don't really want to mix the 2 or at least rely on the process going away.

    Once you're WriteInfoToWordDoc method is done with the app it needs to clean it up so call the Quit method. With the call to Quit I see the process exit after about 1 minute.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Hamed_1983 Friday, January 25, 2019 4:39 PM
    Friday, January 25, 2019 4:27 PM
    Moderator
  • Thanks Michael

    i've add this code at the end of 'WriteInfoToWordDoc' method and works fine!!

    wordApp.Quit(ref saveChanges, ref missing, ref missing);

    Thanks you so much.


    http://www.codeproject.com/KB/codegen/DatabaseHelper.aspx

    Friday, January 25, 2019 4:39 PM