打开多个Office文档时出现多个实例


9

16.0.8625.2121Office 版本开始(已通过Word和Excel测试)-在资源管理器中选择多个文档并按Enter键将其打开时,最终将获得实例数,该数量等于先前所选文档的数量。

要重现,请执行以下步骤:

  • 在计算机上的任意位置创建2个空的Excel工作簿
  • 选择这两个文件
  • 按下Enter
  • 检查Taskmanager,您将看到2个Excel实例

在较早的版本中16.0.8625.2121,最终只有1个实例。

经过测试

  • 16.0.4266.1003 -我们拥有的旧照片比我们更新到的新版本

    officec2rclient.exe /update user updatetoversion=16.0.xxxx.yyyy
    

使用这些新版本逐步进行了重新测试:

  • 16.0.8431.2094
  • 16.0.8431.2107
  • 16.0.8528.2139
  • 16.0.8528.2147

在显而易见的事情被提及之前,就没有DisableMergeInstance定论。

这是一个新的“功能”还是一个错误?我相信这是一个错误。

有办法解决吗?

更多的信息:

我们使用(总是最新版本)测试了此行为

  • Windows 7 + Office 2016-发生不良行为
  • Windows 10 + Office 2016-行为不端

还检查了较旧的Office版本,以确保这是Office 2016年

  • Windows 8 + Office 2013-不会发生
  • Windows 7 + Office 2010-不会发生
  • Windows 10 + Office 2010-不会发生
  • Windows 10 + Office 2013-不会发生

Answers:


6

如果我在整个文章中都重复我的解释,我深表歉意,但是我发现这个问题非常复杂,因此我尝试确保在上下文中对读者有意义:

尽管可能不知道这是错误还是故意的,但我们可以通过创建DDE消息而不是硬参数“%”来使用动态数据交换协议(DDE),通过“动态”数据交换协议(DDE)强制其在“相同”实例中打开。 1”,指向该文件,以便在执行文件时打开该实例。(尽管DDE甚至与hard参数一起使用)。

在这种情况下,DDE消息用于告诉程序打开文件。实际上,对于每个执行的文件,它每次都会创建一个新实例。但是,当使用DDE协议时,它首先检查实例是否已经创建,如果是,它将DDE消息中继到找到的第一个实例,然后退出,从而产生一种幻觉,即所有文件都是在单个实例中即时打开的。

在多个实例中打开文件的问题可能与调用另一个实例时单个实例已经加载了多少有关。第一个实例与第二个实例的执行时间差之间的趋势是,随着两次执行之间的时间增加,它倾向于产生一个实例,而随着时间的减少,它趋向于产生两个实例。这表明如果执行了另一个文件,则必须加载或“准备好”在同一实例中打开一个新文件的第一个实例,否则,它必须与自身一起打开该文件。

似乎当文件路径用作程序的参数时,似乎仅遵循此趋势:

  • Word 2016
  • Excel 2016

如果第一个实例已准备就绪(或如果非第一个实例认为已准备就绪),则用作创建第一个实例之外的实例的参数时,非第一个实例似乎能够将参数作为DDE消息传递给第一个实例。

但是,如果我们执行程序并使用DDE消息打开文件,则无论第一个实例是否准备好通过参数接受DDE消息,似乎都立即遵循DDE协议。第一个实例是否准备就绪可能取决于非第一个实例是否将第一个实例视为已准备就绪,否则,它不会将DDE消息发送给第一个实例,这似乎仅在通过参数打开时发生。在以下情况下,DDE消息(来自非第一者)被第一者接受:以下事实提示了非第一者认为第一者“未准备好”或“不存在”的推测:参数连接“%1”;并通过DDE消息告知它打开。

因此,我的猜测是:这些应用程序的代码使用某种模糊的方法来确定另一个实例是否“就绪”,如果是,则在使用参数时将使用DDE协议。这似乎使用了不同于仅当它接收DDE协议来确定是否将其发送到另一个实例时的方法。实际上,伪代码为:

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();
    }
}

在没有程序员通知我们的情况下,无法断定这是错误还是出于某种原因而变得晦涩难懂。

解析度

我们要调整某些文件扩展名的执行,以不再将正在执行的文件的文件路径(“%1”)作为参数发送,而是告诉正在执行的程序执行DDE消息的内容,其中包含一个打开文件的请求,该请求会将文件中继到一个已经存在的实例(如果存在),并且如果不使用它本身。如果使用文件路径的参数,则可以推测地绕过这些应用程序的晦涩要求,以使另一个实例被视为“就绪”。

这些是与类密钥相关的所有文件扩展名,这些扩展名应替换为x

对于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

对于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

*最重要/最常用的文件扩展名,应至少进行。主观。

†次要的最重要/通用文件扩展名,应至少进行。主观。

这些列表可以通过命令行复制:assoc | findstr WordWord正式的缩写名称(区分大小写)替换。

如果您认为有必要,可以选择所有这些方法。如果您想做更多的事情,您可能希望遵循我将提供的可选步骤,这将减少所需的工作。

对于下面的每个注册表项,您应遵循以下说明,将其替换x为您选择的相应类:

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

(例如:HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\Open

再一次,OpenAsReadOnly密钥是可选的,在执行文件时它将准备好以使其为只读。

小注意事项-备份

为了最好地记住修改之前的注册表值,您可能需要右键单击键分支HKEY_CLASSES_ROOT,然后在上下文菜单下单击“导出”,然后将注册文件保存到某个位置。如果Doc Brown说“我们需要回去”,您可以通过执行注册表项并按照说明导入注册表项。

另外,您也可以运行此命令,以便记住使用以下command方法来解决小错误的值和类名称:

assoc>>fileexts.txt 可以使用过滤 type fileexts.txt | findstr Word

ftype>>classnames.txt 可以使用过滤 type classnames.txt | findstr Word

使用说明

如您所愿,以上列出的每个键值都应遵循这些规则。

输入您最喜欢的注册表编辑器,或者regedit转到您想要修改的类。

输入名为的键command,右键单击该(Default)值,然后单击上下文菜单下的“修改”。

当前设置应该是执行者 ftype | findstr Word

更改它以删除值末尾的直接参数(包括空格),使其变为:

  • "C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE"
    (对于Excel 64位)
  • "C:\Program Files\Microsoft Office\Root\Office16\WINWORD.EXE"
    (对于Word 64位)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\WINWORD.EXE"
    (对于Word 32位)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE"
    (对于Excel 32位)

输入称为键的键ddeexec(如果不存在,请创建键),该键将位于该command键旁边,右键单击该(Default)值,然后单击上下文菜单下的“修改”,并将值设置为:

  • [REM _DDE_Direct][FileOpen("%1")] -(对于Word)
  • [open("%1")] -(适用于Excel)

在下面ddeexec创建一个名为topic(如果不存在)的新键,右键单击该(Default)值,然后单击上下文菜单下的“修改”,然后将值设置为system(如果尚未存在)。

修改之后,您可能需要在注册表中创建以下更改之后,通过使用提升的命令提示符或shell运行shell32.dll来刷新shell32.dll:

regsvr32 /i shell32.dll

已在Windows 10 Office 2016版本16.0.8625.2127上进行测试

替代捷径

您也可以转到文件扩展名的键(例如HKEY_CLASSES_ROOT\.xlsx),然后将“(默认)”值修改为单个类,这种方法(如果遵循的话)可以将多个文件扩展名指向您所使用的同一个类值(例如Excel.Sheet.12)只需使用DDE消息修改一次该类。如果执行此操作,还应该重命名该注册表分支中所有类名称的重复。但是,不建议使用这种方式,因为这种方式很容易中断,如果要进行所有文件扩展名以节省时间,则应这样做。

旁注:

/o参数是URL的参数,因此失去此功能并不是什么大问题,因为它很少被传递。但是,如果您愿意,可以在调整(Default)值时尝试保留参数的这一部分。

我正在考虑使它成为社区Wiki,因为它具有很大的投机性,而且还没有完成(如果Word和Excel不是唯一的)。请对此发表评论。


1

除了@ El8tedN8te的出色回答外,我还指出,对于Excel,没有必要修改ddeexec注册表项。

(Default)项目的值设置为:

"C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE" /dde "%1"

通过我的测试,可以确保仅执行一个Excel实例。


在我看来,这种方法无济于事,它没有在单个实例中运行。我尽力证明自己错了。我重新启动,仔细检查了我是否使用了正确的类名和扩展名,将您的参数翻转了一下,并杀死了“ C2R” .exe。事实上却反其道而行之,即使他们没有被同时打开,额外的参数使他们留下来单独的实例,这是这里承认:social.technet.microsoft.com/Forums/office/en-US/...
El8dN8

@ El8tedN8te:我不知道我们两台计算机之间有什么区别。也许在菜单文件>选项>高级中,在常规下,选择选项“忽略使用动态数据交换(DDE)的其他应用程序”。您的链接确认/dde应强制执行一个实例。
harrymc '17

当我阅读该链接时,我不知道我是否很忙……哈……哈……是的,我检查了该设置……值得研究为什么我的行为有所不同。如果我的电脑是错误的,我的猜测是错误的。请问您的办公版本是什么?
El8dN8

@ El8tedN8te:版本16.0.8625.2121。
harrymc '17

在我的机器上,它也无法正常工作,就像@ El8tedN8te一样。
兰德·兰德(Rand Random)

-1

页面中报告“ Excel中没有MDI兼容性选项。

“ MDI”代表“ 多文档接口”,并且已被SDI(“单文档接口”)取代,因此没有错误。这就是Excel现在工作的方式。

您可以通过按来循环浏览工作簿Ctrl+TAB,然后Ctrl+Shift+TAB向后循环。如果需要,可以安装将此功能添加到整个Office套件的应用程序。检查以下两个选项:

不幸的是,我现在无法测试这些软件。


这不会回答问题,因为即使您提供的链接依次打开两个excel工作表时也说:“在“进程”选项卡上向下滚动,直到看到Excel.exe。请注意,尽管您打开了两个Excel实例,两个工作簿包含在同一 Excel 实例中。” OP创建两个实例的方式(使用与Microsoft相同的方法) “ Excel中没有MDI兼容性选项”这一说法相矛盾,因为出现了多个文档接口(实例),而不是应该在相同的实例中出现。
El8dN8

正如@ El8tedN8te指出的,我所说的是2个实例(2个进程),而不是2个窗口。
兰德·兰德(Rand Random)

我想纠正我先前的评论,提供的报价实际上是正确的。因此,无视我的最后一句话……我的最后评论。我很放肆
El8dN8

很好,@ El8tedN8te。我想知道报价中有什么问题
m2cit
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.