如果我在整个文章中都重复我的解释,我深表歉意,但是我发现这个问题非常复杂,因此我尝试确保在上下文中对读者有意义:
尽管可能不知道这是错误还是故意的,但我们可以通过创建DDE消息而不是硬参数“%”来使用动态数据交换协议(DDE),通过“动态”数据交换协议(DDE)强制其在“相同”实例中打开。 1”,指向该文件,以便在执行文件时打开该实例。(尽管DDE甚至与hard参数一起使用)。
在这种情况下,DDE消息用于告诉程序打开文件。实际上,对于每个执行的文件,它每次都会创建一个新实例。但是,当使用DDE协议时,它首先检查实例是否已经创建,如果是,它将DDE消息中继到找到的第一个实例,然后退出,从而产生一种幻觉,即所有文件都是在单个实例中即时打开的。
测
在多个实例中打开文件的问题可能与调用另一个实例时单个实例已经加载了多少有关。第一个实例与第二个实例的执行时间差之间的趋势是,随着两次执行之间的时间增加,它倾向于产生一个实例,而随着时间的减少,它趋向于产生两个实例。这表明如果执行了另一个文件,则必须加载或“准备好”在同一实例中打开一个新文件的第一个实例,否则,它必须与自身一起打开该文件。
似乎当文件路径用作程序的参数时,似乎仅遵循此趋势:
如果第一个实例已准备就绪(或如果非第一个实例认为已准备就绪),则用作创建第一个实例之外的实例的参数时,非第一个实例似乎能够将参数作为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 Word
用Word
正式的缩写名称(区分大小写)替换。
如果您认为有必要,可以选择所有这些方法。如果您想做更多的事情,您可能希望遵循我将提供的可选步骤,这将减少所需的工作。
对于下面的每个注册表项,您应遵循以下说明,将其替换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不是唯一的)。请对此发表评论。