Peço desculpas se reiterar minhas explicações por toda parte, mas considero esse assunto muito complexo, por isso tentei garantir que contextualmente faça sentido para os leitores:
Embora não se saiba se isso é um bug ou se foi intencional, podemos forçá-lo a abrir na instância "mesma" usando o protocolo DDE (Dynamic Data Exchange Protocol) criando uma mensagem DDE em vez do argumento "% 1 "apontando para o arquivo para a instância abrir ao executar o arquivo. (Embora o DDE seja usado mesmo com o argumento rígido).
A mensagem DDE, neste caso, é usada para dizer ao programa para abrir um arquivo. Para cada arquivo executado, ele realmente cria uma nova instância sempre. Porém, quando o protocolo DDE é usado, ele primeiro examina se uma instância já foi criada e, em caso afirmativo, retransmite a mensagem DDE para a primeira instância encontrada e sai, dando a ilusão de que todos os arquivos são abertos em uma única instância, pois são instantâneos.
Especulações
O problema da abertura de arquivos em várias instâncias provavelmente tem a ver com o quanto uma única instância já foi carregada quando outra instância está sendo chamada. A tendência entre a diferença no tempo de execução de uma primeira e uma segunda instância é que, conforme o tempo entre execuções aumenta, ela tende a render uma única instância e, à medida que diminui, tende a produzir duas instâncias. Isso sugere que a primeira instância deve estar carregada ou "pronta" para abrir um novo arquivo na mesma instância, se outro arquivo for executado e, caso contrário, deverá abrir o arquivo consigo.
Parece que quando o caminho do arquivo é usado como argumento para o programa, parece seguir esta tendência apenas:
Quando usada como argumento para criar instâncias além da primeira instância, se a primeira estiver pronta (ou se os primeiros não acharem que está pronta), a não-primeira instância parece capaz de retransmitir o argumento como uma mensagem DDE para a primeira.
No entanto, se executarmos o programa e usarmos uma mensagem DDE para abrir o arquivo, parece seguir o protocolo DDE imediatamente se a primeira instância está pronta ou não para aceitar a mensagem DDE via argumento. A probabilidade de a primeira instância estar ou não pronta depende se o primeiro não vê a primeira instância como pronta e, caso contrário, não envia a mensagem DDE para a primeira, o que parece ocorrer apenas quando é aberto via argumento . A especulação do não-primeiro que vê o primeiro como não "pronto" ou "inexistente" é sugerida pelo fato de que as mensagens DDE (de não-primeiros) são aceitas pelo primeiro quando: o não-primeiro não é executado via uma concatenação de argumento "% 1"; e é dito para abrir através de uma mensagem DDE.
Como tal, minha especulação é: o código para esses aplicativos usa algum método obscuro para determinar se outra instância está "pronta" e, se assim for, usaria o protocolo DDE quando um argumento for usado. Isso parece usar um método diferente do que quando recebe o protocolo DDE para determinar se deve enviá-lo para outra instância. Aparentemente, o pseudocódigo era:
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();
}
}
Não há como saber se isso é um bug ou se foi pretendido que ele fosse obscuro por um motivo, sem que os programadores nos informassem.
A resolução
Queremos ajustar a execução de determinadas extensões de arquivo para não enviar mais o caminho do arquivo ("% 1") do arquivo que está sendo executado como argumento, mas dizer ao programa que está sendo executado para executar o conteúdo da mensagem DDE, da qual contém uma solicitação para abrir um arquivo, que o retransmitirá para uma instância já existente, se existir e se não for o próprio uso. Que especulativamente, ignorará os requisitos obscuros desses aplicativos para que outra instância seja vista como "pronta" se um argumento para o caminho do arquivo for usado.
Essas são todas as extensões de arquivo correlacionadas às chaves de classe que devem ser substituídas por x
:
Para o 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
Para 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
* As extensões de arquivo mais importantes / comuns que devem ser feitas no mínimo. Subjetivo.
† Extensões de arquivo secundárias mais importantes / comuns que devem ser executadas no mínimo. Subjetivo.
Essas listas podem ser replicadas pela linha de comando: assoc | findstr Word
substituindo Word
pelo nome abreviado oficial (diferencia maiúsculas de minúsculas).
Tudo o que você tem a opção de fazer se achar necessário. Se quanto mais você quiser, siga as etapas opcionais que darei, o que reduzirá o trabalho necessário.
Você deve seguir as instruções a seguir para cada chave do registro abaixo, substituindo a x
(s) classe (s) correspondente (s) de sua escolha:
HKEY_CLASSES_ROOT\x\shell\Open
HKEY_CLASSES_ROOT\x\shell\OpenAsReadOnly
(Ex: HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\Open
)
Mais uma vez, a OpenAsReadOnly
chave é opcional. Isso ficará pronto quando o arquivo for executado, de modo que seria somente leitura.
Uma pequena precaução - um backup
Para lembrar melhor quais eram os valores do registro antes da modificação, clique com o botão direito do mouse na ramificação da chave HKEY_CLASSES_ROOT
e, no menu de contexto, clique em "Exportar" e salve o arquivo de registro em um local. Caso o Doc Brown diga "Precisamos voltar", você pode importar a chave do Registro executando-a e seguindo as instruções.
Como alternativa, você também pode executar isso para lembrar quais command
eram os valores e nomes de classe para corrigir pequenos erros com:
assoc>>fileexts.txt
que pode ser filtrado usando type fileexts.txt | findstr Word
ftype>>classnames.txt
que pode ser filtrado usando type classnames.txt | findstr Word
Instruções
Eles devem ser seguidos para todos os valores-chave listados acima, como você deseja fazer.
Entre no seu editor de registro favorito ou regedit
vá para a turma que deseja modificar.
Digite a chave chamada command
, clique com o botão direito do mouse no (Default)
valor e clique em "Modificar" no menu de contexto.
Atualmente definido deve ser o que foi executado por ftype | findstr Word
Altere-o para remover os argumentos diretos no final do valor, incluindo o espaço, para se tornar:
"C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE"
(Para Excel de 64 bits)
"C:\Program Files\Microsoft Office\Root\Office16\WINWORD.EXE"
(Para Word de 64 bits)
"C:\Program Files (x86)\Microsoft Office\Root\Office16\WINWORD.EXE"
(Para Word de 32 bits)
"C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE"
(Para Excel de 32 bits)
Digite a chave chamada ddeexec
(se ela não existir, crie a chave) que estaria ao lado da command
chave, clique com o botão direito do mouse no (Default)
valor e clique em "Modificar" no menu de contexto e defina o valor para:
[REM _DDE_Direct][FileOpen("%1")]
- (Para Word)
[open("%1")]
- (Para Excel)
Abaixo, ddeexec
crie uma nova chave chamada topic
(se ela não existir), clique com o botão direito do mouse no (Default)
valor e clique em "Modificar" no menu de contexto e defina o valor para se tornar system
(se ainda não existir).
Após as modificações, talvez seja necessário atualizar o shell32.dll executando-o com um prompt de comando ou shell elevado após a criação dessas alterações no registro:
regsvr32 /i shell32.dll
Isso foi testado em um Windows 10 Office 2016 versão 16.0.8625.2127
Atalho alternativo
Você também pode acessar a chave para extensões de arquivo (como HKEY_CLASSES_ROOT\.xlsx
) e modificar o valor "(Padrão)" para uma classe singular. Essa abordagem, se seguida, pode apontar várias extensões de arquivo para o mesmo valor de classe (como Excel.Sheet.12
) que você só precisa modificar essa classe uma vez com a mensagem DDE. Se você fizer isso, renomeie todas as reiterações do nome da classe dentro dessa ramificação do registro. No entanto, esse caminho não é recomendado, pois pode ser interrompido facilmente e deve ser feito se você fizer todas as extensões de arquivo para economizar tempo.
Sidenotes:
O /o
argumento é um argumento para URLs, portanto, não é uma grande preocupação em perder essa funcionalidade, pois raramente é passada. No entanto, se desejar, você pode tentar deixar essa parte do argumento ativada ao ajustar os (Default)
valores.
Estou pensando em fazer deste um wiki da comunidade, pois é muito especulativo e também inacabado (se o Word e o Excel não fossem os únicos). Por favor, comente uma opinião sobre isso.