0

I wrote a WCF print MS Word document service. This service is called from multiple PCs. The print method gets as parameter, the MS document path (on the network) and the printer name (printers are on the network).

The problem is when 2 users print on the same time, there could be a chance that the 2 printed documents will be printed on the same printer. The reason is because the way we define where to print the MS document using Word Interop. When printing a word document using interop, we need to set the active printer to the printer name. Therefore, if 2 users print on the same time, the last one that send the print request, will change the active printer and cause the fist document of the first user to be printed on the second printer.

Following the Print method I wrote:

using wd = Microsoft.Office.Interop.Word;
class WordWrapper
{
    private readonly wd.Application _wdApp;

    public WordWrapper()
    {
        _wdApp = new wd.Application();
    }

    internal void Print(string wordPath, string printerName)
    {
        int referenceCount;
        wd.Documents wdDocuments = null;
        wd.Document wdDocument = null;

        try
        {
            wdDocuments = _wdApp.Documents;
            wdDocument = wdDocuments.Open(wordPath);

            try
            {
                _wdApp.DisplayAlerts = wd.WdAlertLevel.wdAlertsNone;
                _wdApp.ActivePrinter = printerName; // THIS LINE CHANGE THE ACTIVE PRINTER
                wdDocument.PrintOut();
            }
            catch (COMException ex)
            {
                if (ex.ErrorCode == -2146827284)
                {
                    throw new WordFileOpenException();
                }
            }
            finally
            {
                _wdApp.DisplayAlerts = wd.WdAlertLevel.wdAlertsAll;

                wdDocument.Close(true);
                wdDocuments.Close();
            }
        }
        finally
        {
            referenceCount = ReleaseWordObject(wdDocuments);
        }
    }
}

The question is: how can I lock to prevent 2 users changing the active printer on the same time?

ehh
  • 3,412
  • 7
  • 43
  • 91
  • Have you read http://stackoverflow.com/questions/11126065/how-to-print-a-docx-to-a-specific-printer-using-microsoft-office-interop-word-do which has a way of doing it without changing the printer overall just for that print? – BugFinder Feb 07 '17 at 08:15
  • Yes but it says that you can't print without changing the default printer as I mention in my question – ehh Feb 07 '17 at 08:16
  • Then your only choice would be to implement a stack - and that print requests are in the stack - so that you change the printer for a print, and then start the next – BugFinder Feb 07 '17 at 08:17
  • OK, interesting. Can you please give more details. How this stack will be known by all printing users, each one will print from a different exe application. – ehh Feb 07 '17 at 08:19
  • you said you have a WCF that collects all the print requests - you implement the stack, you queue them, and print them, so that you only ever print one at a time. To simplify it you would probably split out the printing into a service so that it does the queue, the WCF takes the requests and validates all it needs to – BugFinder Feb 07 '17 at 08:20
  • Or you could do a dirty hack of create a local file of "printing" in temp, and while that exists no one else can print until one job completes and deletes the file, and then next one to grab etc.. – BugFinder Feb 07 '17 at 08:23
  • I don't see how can implement the stack since the service is a different instance for each user printing and therefore the stack is also a different instance for each one. What am I missing? – ehh Feb 07 '17 at 08:40
  • As said, you would probably do best to split out the actual printing into a service - that wont be multi instance, the WCF would pass the requests to that, which would stack them, or implement a file lock option – BugFinder Feb 07 '17 at 08:42
  • Understood, thanks for your help – ehh Feb 07 '17 at 08:44

0 Answers0