Suppressing the MODI Popup using C#

For those of you who have never heard of the MODI acronym it stands for
the Microsoft Office Document Image writer, which is a virtual printer
driver for converting printed content into Microsoft Document Images or
TIFF files. The idea for this virtual printer, shipped with Office, is
to provide a means for converting output from applications with
printing ability into a format that can be read by Office applications.

I am working on a project that converts known file formats into TIFF
images, so MODI is ideal for this task. The project involves converting
multiple files at once, using multi-threading. Converting Office type
documents with MODI was easy, Word, Excel, PowerPoint
etc, provide printing ability using a COM API. The method call in these
application interfaces requires a printer name and filename to save to,
if using virtual printers like MODI. Life is good. The problem comes
about when using non-Office applications, such as Internet Explorer,
to print using MODI. The print method in IE’s API does not provide a
way to specify the output file, as with the Office applications, so
during the print request MODI pops up a helpful dialog box – great in a
single thread printing environment, bad in a multi-threaded application
with lots of print jobs.

I scoured the web looking for a quick fix to the MODI pop up problem but
found very little help. Microsoft provides an API for MODI but it is
designed for sending documents to the driver, not manipulating the
driver options. The only helpful hint I came across was to post
or send messages to the dialog window that MODI pops up, thus simulating a user
pressing the “save” button. Using this idea I got to work on writing a
class that would manipulate the MODI pop up window from C#.

I wrote a simple class that will manipulate any instance of  MODI
pop up window that is found on the system. The class uses Win32 API
calls to find the “Save As” window with the same characteristics used
by MODI. Once found I can send Windows messages to the controls on the
form to change the file name location and click the save button.
MODI typically displays the pop up window a short time after a print
request has been made. This time is dependent on the sized of the data
being sent to the MODI printer. Most applications use the spooler to
print to MODI and the print call is asynchronous, meaning the call will
return immediately after spooling before printing starts. It is not
enough to detect the pop up window directly after a print method
invocation
because the MODI may still be busy and the pop up will be missed. So I
wrote functionality into my class to wait for an expected MODI pop up
window for a finite period of time.

Below is an example of how to call my class using C#. My class can also
be called from VB.Net, or any other .Net language, only the syntax will
change accordingly.

// Called after a print method invocation.
// Wait 5 seconds for the window to appear.
// If the null is returned no window could be detected.
MODIWindow window = MODIWindow.WaitForWindow(5);
if (null != window)
{
// Change the filename.
window.Filename = “c:newfile.mdi”;
// Make the window go away by simulating clicking save.
window.Save();
}

The code for the MODI Window class can be found Here.

18 thoughts on “Suppressing the MODI Popup using C#

  1. http://

    Check this lines. They update the windows registry to the popup never show it.
    <br>
    <br>ModificarAtributo(@&quot;SoftwareMicrosoftOffice11.0MODIMDI Writer&quot;, &quot;PrivateFlags&quot;, 1, TypeRegistry.CurrentUser);
    <br>
    <br>ModificarAtributo(@&quot;SoftwareMicrosoftOffice11.0MODIMDI Writer&quot;, &quot;OpenInMODI&quot;, 0, TypeRegistry.CurrentUser);
    <br>
    <br>One question: do you know how i can do persistent annotations in all my documents mdi or tif?
    <br>
    <br>My email is samsagaz23@wanadoo.es.
    <br>
    <br>tx.
    <br>

  2. http://

    Amazing! How does one go about discovering obscure registry settings like PrivateFlags?!
    <br>
    <br>I tried this and it works, but the file is always written as Note0001.mdi.
    <br>
    <br>How would I change the type to TIFF, and the name to whatever I want?
    <br>
    <br>Thanks

  3. http://

    Can u please give some more code how to make a print out in background with MODI, suppresing popup and tiff

  4. http://

    Thank you so much for the information. Private Key settings works grate. I was searching for this almost a day now. I could not find it any where else.
    <br>
    <br>This settings copies the file in MDI. Is there any way you can do it for
    <br>TIFF?
    <br>
    <br>THANK YOU šŸ™‚

  5. http://

    Use decimal value of 35 (i.e. 1f in hexadecimal) for converting to tiff without displaying the save as dialog box.
    <br>
    <br>

  6. http://

    when i try to print the PDF file using MODI printer through my class library project (dll), which is registered on the server, the MODI popup window where we can specify the output filename is suppressed. Since the popup window is not visible, FindWindowEx fails to locate the &quot;Save As&quot; window. Is there a way we can get around this problem.
    <br>
    <br>Thanks
    <br>
    <br>Rahul

  7. http://

    Here’s some code I just wrote:
    <br>
    <br>Using 17 for PrivateFlags gives me Note.tif in the temp directory with no save as dialog.
    <br>
    <br>The DPI setting of 600 does work, although I’d suggest 200 or 300 for real code. 2400 even works, if you want a real large file.
    <br>
    <br>
    <br> private int iMODICOMPIMGEMF;
    <br> private string sMODIPath;
    <br> private int iMODIPrivateFlags;
    <br> private int iMODIPublic_Orientation;
    <br> private int iMODIPublic_PaperSize;
    <br> private int iMODITIFDPI;
    <br> private int iMODIOpenInMODI;
    <br>
    <br> private string sMODIKey = @&quot;HKEY_CURRENT_USERSoftwareMicrosoftOffice11.0MODIMDI writer&quot;;
    <br> private void SaveMODIKeys()
    <br> {
    <br> iMODICOMPIMGEMF = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;COMPIMGEMF&quot;, 0);
    <br> sMODIPath = (string) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;DefaultFolder&quot;, @&quot;C:&quot;);
    <br> iMODIPrivateFlags = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;PrivateFlags&quot;, @&quot;C:&quot;);
    <br> iMODIPublic_Orientation = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;Public_Orientation&quot;, @&quot;C:&quot;);
    <br> iMODIPublic_PaperSize = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;Public_PaperSize&quot;, @&quot;C:&quot;);
    <br> iMODITIFDPI = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;TIFDPI&quot;, @&quot;C:&quot;);
    <br> iMODIOpenInMODI = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;OpenInMODI&quot;, 0);
    <br>
    <br> }
    <br>
    <br> private void SetMyMODIKeys()
    <br> {
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;COMPIMGEMF&quot;, 1);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;DefaultFolder&quot;, @&quot;C:temp&quot;);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;PrivateFlags&quot;, 17);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;Public_PaperSize&quot;, 1);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;Public_Orientation&quot;, 1);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;TIFDPI&quot;, 600);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;OpenInMODI&quot;, 0);
    <br> }
    <br>
    <br> private void RestoreMODIKeys()
    <br> {
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;COMPIMGEMF&quot;, iMODICOMPIMGEMF);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;DefaultFolder&quot;, sMODIPath);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;Public_Orientation&quot;, iMODIPrivateFlags);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;Public_PaperSize&quot;, iMODIPublic_Orientation);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;Public_PaperSize&quot;, iMODIPublic_PaperSize);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;TIFDPI&quot;, iMODITIFDPI);
    <br> Microsoft.Win32.Registry.SetValue(sMODIKey, &quot;OpenInMODI&quot;, iMODIOpenInMODI);
    <br> }
    <br>

  8. Fred

    Oops, wrong default values there
    <br>
    <br> private void SaveMODIKeys()
    <br> {
    <br> iMODICOMPIMGEMF = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;COMPIMGEMF&quot;, 0);
    <br> sMODIPath = (string) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;DefaultFolder&quot;, @&quot;C:&quot;);
    <br> iMODIPrivateFlags = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;PrivateFlags&quot;, 0);
    <br> iMODIPublic_Orientation = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;Public_Orientation&quot;, 1);
    <br> iMODIPublic_PaperSize = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;Public_PaperSize&quot;, 1);
    <br> iMODITIFDPI = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;TIFDPI&quot;, 300);
    <br> iMODIOpenInMODI = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, &quot;OpenInMODI&quot;, 1);
    <br> }
    <br>

  9. http://

    Hey guys, thanks for this thread!! It has been a great reference point! However I am having one problem.

    I am writing an automation application for IBM’s content manager, in which I would like to print to a .tif file, then send to our Fax printer. (I cannot directly print to the fax printer, because I am going some database work in between). Anyhow, through IBM’s automation API’s, even if I have OpenInMODI=0, it still pops up when its done printing.

    Has anyone else had this type of issue (where MODI is popping up, even though OpenInMODI=0)?

    Thanks!!

  10. http://

    Note: I’ve temporarily solved my problem by spawning a process that looks for instances of “mspview.exe” and kills them ;), cheap, but for now it works.

    I’m guessing that IBM’s API’s are, for some reason trying to open the document upon a successful print.

  11. Yolanda

    Fred said:
    Using 17 for PrivateFlags gives me Note.tif in the temp directory with no save as dialog.
    A perfect tip. Does anybody know how I can change the file name automatically. E.g. I like to create a MDI with file name Invoice_12345.mdi when I am printing the invoice

    Any help will help me
    Yolanda

  12. http://

    I have been looking for this information for some time now. I was trying to print a large amount of TEXT files through MODI to TIF format. Using 17 for PrivateFlags gives Note.tif in the temp directory with no save as dialog will be a big help for me. However, like Yolanda mentioned, it would be great if one can specify the output file name. Since no one has found a way to do that yet, I guess one solution would be to rename/copy the Note.tif to youfilename.tif after the printing finishes.

    So my question is how you can detect that the printing has finished and Note.tif has been closed before I do the rename?

    I have been using window scripting to print thousands of text files, it worked most of the time. I’d like to impement a more reliable solution in C#. Any help will be really appreciated.

  13. http://

    private void convertToTiff(object sfile, object dfile)
    {
    object o_null = System.Reflection.Missing.Value;
    object missingValue = System.Reflection.Missing.Value;
    object bak = true;
    Word.Document doc = null;
    object myTrue = true;
    object myFalse = false;
    try
    {
    doc = wordApp.Documents.OpenOld(ref sfile,ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue);
    doc.PrintOutOld(ref myTrue,ref myFalse, ref missingValue,ref dfile, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref myTrue, ref missingValue, ref missingValue, ref missingValue);
    }
    finally
    {
    if (doc != null)
    doc.Close(ref o_null,ref o_null,ref o_null);
    }
    }

  14. http://

    In response to Frank Morris’s question concerning how to find obscure registry options, I have done this in the past with the aid of Sysinternals “RegMon” utility. Originally-written by Mark Russinovich independently of Microsoft, but Mark now works for Microsoft and they have fortunately kept all of his extremely useful utilities available for download. RegMon is available at http://technet.microsoft.com/en-us/sysinternals/bb896652.aspx

    What I do is look for “NOTFOUND” results when a program is starting, which signify attempts by the software to read registry keys which don’t exist. That at least identifies keys which might possibly be used by the software in question.

    Running this utility filtered to the MSPVIEW.EXE application should result in a list of registry calls made by MODI.

  15. Mike

    Hi there

    Could someone please post the code for the MODI Window class Rod mentions above. The dowmnload link is broken.

    I volunteer my time at baseball park and would like to automate the printing of registrations as TIFFs.

    Thanks in advance

    –Mike

  16. estuardogt

    Hi sir,

    I really apreciate some of help… I need to convert files (word, excel, power point and pdf) to Tiff format.
    I tried with MODI Api, but the problem it is that MODI just take valid document with format .TIFF with other files shows me an error like this “The files is empty or corrupted”
    Please, please, Could you give me any idea how to resolve it?

    Thank you so much!!!

Comments are closed.