Multiple instances upon opening multiple Office Documents

I apologize if I reiterate my explanations throughout, but I find this issue very complex so I tried to ensure it contextually makes sense to readers:

While it may not be known whether this is a bug or it was intended, we can force it to open in the "same" instance by using the Dynamic Data Exchange protocol (DDE) by creating a DDE message instead of the hard argument "%1" pointing to the file for that instance to open when executing the file. (Although, DDE is used even with the hard argument).

The DDE Message, in this case, is used to tell the program to open a file. For every file executed it actually creates a new instance every time. But when the DDE protocol is used, it firsts examines whether an instance is already created and if so it relays the DDE message to the first instance found and exits thus giving the illusion that all files open in a single instance as it is instantaneous.

Speculations

The issue of the files opening in multiples instances likely has to do with how much a single instance has already loaded when another instance is being called. The trend between the execution time difference of a first an second instance is as the time in between executions increases it tends to yield a single instance and as it decreases it tends to yield two instances. This suggests that the first instance must be loaded or "ready" to open a new file in that same instance if another file is executed, and if isn't it shall open the file with itself.

It seems when the file path is used as an argument to the program, it seems to follow this trend for only:

  • Word 2016
  • Excel 2016

When used as an argument for creating instances beyond the first instance if the first is ready (or if non-firsts see that is ready), the non-first instance seems to be able to relay the argument as a DDE message to the first.

However, if we execute the program and use a DDE message to open the file, it seems to follow the DDE protocol right away whether or not the first instance is ready to accept the DDE message via argument. Whether or not the first instance is ready likely depends if the non-first sees the first instance as ready, and if it doesn't it won't send the DDE message to the first, which seems to only occur when it opens via argument. The speculation of the non-first seeing the first as not "ready" or "non-existent" is suggested by the fact that DDE messages (from non-firsts) are accepted by the first when: the non-first is not executed via an argument concatenation "%1"; and it is told to open via a DDE message.

As such my speculation is: the code for these applications use some obscure method for determining whether another instance is "ready" and if so would then use the DDE protocol when an argument is used. This seems to use a different method than just when it receives the DDE protocol for determining if to send it to another instance. It would appear in effect the pseudocode was:

if(argrument.wasUsed()){
    // Office's obscure condition
    if(Office.thinksInstanceIsReady(anotherInstance)){
        // Use DDE Protocol
        if(anotherInstance.exists()){ // already knew that
            sendDDEmessage(anotherInstance);
            exitThisInstance();
        }
    } else {
        selfFollowDDEmessage(); // Leave open this instance
    }
if(givenDDEMessage()){
    // Use DDE Protocol
    if(anotherInstance.exists()){
        sendDDEmessage(anotherInstance);
        exitThisInstance();
    } else {
        selfFollowDDEmessage();
    }
}

There is no way of telling if this is a bug or it was intended to be obscure for a reason, without the programmers informing us.

The Resolution

We want to adjust the execution of certain file extensions to no longer send the file path ("%1") of the file being executed as an argument, but rather tell the program being executed to perform to the contents of DDE message, of which contains a request to open a file, which will relay it to an already existent instance if exists and if not use it itself. Which speculatively, will bypass the obscure requirements of these applications for another instance to be seen as "ready" if an argument to the file path is used.

These are all file extensions correlated to Class keys which shall be substituted with x:

For Word

FILEEXT          CLASS NAME (x)
 .doc*           Word.Document.8
 .docm†    Word.DocumentMacroEnabled.12
 .docx*         Word.Document.12
 .dot            Word.Template.8
 .dotm†    Word.TemplateMacroEnabled.12
 .dotx†         Word.Template.12
 .odt        Word.OpenDocumentText.12
 .rtf†             Word.RTF.8
 .wbk             Word.Backup.8
 .wiz             Word.Wizard.8
 .wll             Word.Addin.8

For Excel

FILEEXT             CLASS NAME (x)
 .csv*                Excel.CSV
 .ods       Excel.OpenDocumentSpreadsheet.12
 .slk                 Excel.SLK
 .xla                Excel.Addin
 .xlam†        Excel.AddInMacroEnabled
 .xld                Excel.Dialog
 .xlk                Excel.Backup
 .xll                 Excel.XLL
 .xlm              Excel.Macrosheet
 .xls*              Excel.Sheet.8
 .xlsb†     Excel.SheetBinaryMacroEnabled.12
 .xlshtml           Excelhtmlfile
 .xlsm†       Excel.SheetMacroEnabled.12
 .xlsx*             Excel.Sheet.12
 .xlt†             Excel.Template.8
 .xlthtml          Excelhtmltemplate
 .xltm†        Excel.TemplateMacroEnabled
 .xltx†             Excel.Template
 .xlw               Excel.Workspace
 .xlxml               Excelxmlss

* The most important/common file extensions that should be done as a minimum. Subjective.

† Secondary most important/common file extensions that should be done for as a minimum. Subjective.

These lists can be replicated through command-line: assoc | findstr Word replacing Word with the official shortened name (case-sensitive).

All of which you have the option to do if you feel it is necessary. If the more you want to do you might want to follow the optionable steps which I shall provide, which should reduce the work needed.

You shall follow the following instructions for every registry key below replacing the x with the corresponding Class(es) of your choice(s):

  • HKEY_CLASSES_ROOT\x\shell\Open
  • HKEY_CLASSES_ROOT\x\shell\OpenAsReadOnly

(Ex : HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\Open)

Once again, the OpenAsReadOnly key, is optionable this will ready when the file is executed such that it would be read-only.

A small precaution - a backup

To best remember what the registry values were before modification, you may want to go to right-click the key branch HKEY_CLASSES_ROOT, and under the context menu click "Export" and save the Registration File to a location. In case Doc Brown says "We need to go back," you can just import the registry key by executing it and following the instructions.

Alternatively, you can also run this so you remember what the command values and Class names were to fix small mistakes with:

assoc>>fileexts.txt which can be filtered using type fileexts.txt | findstr Word

ftype>>classnames.txt which can be filtered using type classnames.txt | findstr Word

Instructions

These shall be followed for every key value listed above, as you desire to do.

Enter unto your favorite registry editor or regedit and go to the Class you wish to modify.

Enter into the key called command, right-click the (Default) value, and click "Modify" under the context menu.

Currently set should be what was executed by ftype | findstr Word

Change it to remove the direct arguments at the end of the value, including the space, to become:

  • "C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE"
    (For Excel 64-bit)
  • "C:\Program Files\Microsoft Office\Root\Office16\WINWORD.EXE"
    (For Word 64-bit)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\WINWORD.EXE"
    (For Word 32-bit)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE"
    (For Excel 32-bit)

Enter into the key called ddeexec (if it does not exist, create the key) which would be beside the command key, right-click the (Default) value, and click "Modify" under the context menu, and set the value to become:

  • [REM _DDE_Direct][FileOpen("%1")] - (For Word)
  • [open("%1")] - (For Excel)

Underneath ddeexec create a new key called topic (if it does not exist), right-click the (Default) value, and click "Modify" under the context menu, and set the value to become system (if not already).

After the modifications you may have to refresh shell32.dll by running this with an elevated Command Prompt or shell after creating these changes to the registry:

regsvr32 /i shell32.dll

This has been tested on a Windows 10 Office 2016 Version 16.0.8625.2127

Alternative shortcut

You can also go to the key for file extensions (such as HKEY_CLASSES_ROOT\.xlsx) and modify the "(Default)" value to a singular class, this approach, if followed, can point multiple file extensions to the same Class value (such as Excel.Sheet.12) which you only have to modify that class once with the DDE Message. If you do this one should also re-name all reiterations of the Class name inside that registry branch. However, this way is not recommended, as it could easily break, and should be done if you were to do all file extensions to save time.

Sidenotes:

The /o argument is an argument for URLs, so isn't a big concern in losing this functionality as it rarely is passed. However, if you so wish, you can try and leave this part of the argument on when adjusting the (Default) values.

I am considering to make this a community wiki, since it is very speculative and also unfinished (if Word & Excel were not the only ones). Please comment an opinion on this.