2017-04-03 1 views
0

J'ai une application C# WinForm qui ouvre et remplit un modèle MS Word dotx en plaçant du texte sur les signets, puis tente de l'imprimer, tout en utilisant MS Word Interop 15.Le document imprimé via Word Interop disparaît immédiatement de la file d'attente d'impression

Tout semble aller bien, la boîte de dialogue d'impression s'affiche et se termine OK, le travail d'impression apparaît dans la file d'attente d'impression (par exemple "Périphériques et imprimantes" sous MS Windows 10). Mais alors le travail disparaît immédiatement de la file d'attente avant qu'il puisse être spoulé! (Document apparaît très brièvement avec le statut de « spool », et n'imprime pas - l'imprimante ne fait jamais le travail)

Voici mon code (exception vérification supprimée par souci de concision):

using Word = Microsoft.Office.Interop.Word; 
private void Print_Click(object sender, EventArgs e) 
{ 
    // Open the MS Word application via Office Interop 
    Word.Application wordApp = new Word.Application(); 
    Word.Document wordDoc; 
    // Open the template 
    wordDoc = wordApp.Documents.Add(Template: ContractTemplatePath, Visible: false); 
    // Ensure the opened document is the currently active one 
    wordDoc.Activate(); 

    // Set the text for each bookmark from the corresponding data in the GUI 
    SetBookmarkText(wordDoc, "Foo", fooTextBox.Text); 
    // ... There's a whole bunch of these ... then: 

    // Instantiate and configure the PrintDialog 
    var pd = new PrintDialog() 
    { 
     UseEXDialog = true, 
     AllowSomePages = false, 
     AllowSelection = false, 
     AllowCurrentPage = false, 
     AllowPrintToFile = false 
    }; 

    // Check the response from the PrintDialog 
    if (pd.ShowDialog(this) == DialogResult.OK) 
    { 
     // Print the document 
     wordApp.ActivePrinter = pd.PrinterSettings.PrinterName; 
     wordDoc.PrintOut(Copies: pd.PrinterSettings.Copies); 
    } 

    // Close the document without saving the changes (once the 
    // document is printed we don't need it anymore). Then close 
    // the MS Word application. 
    wordDoc.Close(SaveChanges: false); 
    wordApp.Quit(SaveChanges: false); 
} 

La seule chose Je peux penser ici que peut-être parce que je fais disparaître le document dès que je l'ai envoyé à l'imprimante, alors le travail n'a pas été complètement envoyé ainsi il se retire ou quelque chose. Si ce est le cas alors comment puis-je déterminer combien de temps je dois garder le document pour et quelle est la meilleure façon d'attendre cela? J'ai fait un autre petit peu de recherche (ne pas avoir le temps d'en savoir plus là-dessus), ce qui suggère que je pourrais utiliser l'événement PrintEnd, mais je ne pouvais pas voir immédiatement si cela serait possible. être applicable lors de l'utilisation d'Interop. Serait-ce une méthode de réaliser ce que je veux sans interrogation?

+1

Vous pourriez interroger pour le compte de 'wordApp.BackgroundPrintingStatus' et attendez qu'il soit 0. Je ne peux pas tester cela pour vérifier donc juste un commentaire. – Equalsk

+0

@ Equalsk J'ai fini par utiliser la méthode que vous suggérez (bien que je n'aime pas polling ... Je suppose que je pourrais le faire sur un fil séparé). de toute façon, si vous voulez répondre au même effet, je l'accepterai. – Toby

Répondre

1

Une solution consiste à interroger la propriété BackgroundPrintingStatus de l'application Word. Il contient le nombre de documents en attente dans la file d'attente d'impression. Bien que ce nombre soit supérieur à 0, certains documents sont en attente d'impression.

Il existe plusieurs façons d'y parvenir. Voici une simple boucle qui bloque l'interface utilisateur:

// Send document to printing queue here... 

while (wordApp.BackgroundPrintingStatus > 0) 
{ 
    // Thread.Sleep(500); 
} 

// Printing finished, continue with logic 

Sinon, vous voudrez peut-être de l'envelopper dans une tâche de sorte que vous pouvez faire d'autres choses en attendant:

await Task.Run(async() => { while (wordApp.BackgroundPrintingStatus > 0) 
            { await Task.Delay(500); } });