web-dev-qa-db-fra.com

Plusieurs instances lors de l'ouverture de plusieurs documents Office

À partir de la version 16.0.8625.2121 d'Office (testé avec Word et Excel) - lorsque vous sélectionnez plusieurs documents dans l'Explorateur et que vous appuyez sur Entrée pour les ouvrir, vous obtenez des instances équivalentes au nombre de documents sélectionnés précédemment.

Pour reproduire, procédez comme suit:

  • Créez 2 classeurs Excel vides n'importe où sur votre machine
  • Sélectionnez ces 2 fichiers
  • Appuyez sur Entrée
  • Vérifiez Taskmanager et vous verrez 2 instances d'Excel

Dans les versions antérieures à 16.0.8625.2121, vous vous retrouveriez avec une seule instance.

Testé avec

  • 16.0.4266.1003 - assez vieille image que nous avions autour de nous avons mis à jour pour les versions plus récentes avec

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

Re-testé étape par étape avec ces nouvelles versions:

  • 16.0.8431.2094
  • 16.0.8431.2107
  • 16.0.8528.2139
  • 16.0.8528.2147

Avant que l'évidence ne soit mentionnée, DisableMergeInstance n'est pas défini.

Est-ce une nouvelle "fonctionnalité" ou un bug? Je crois que c'est un bug.

Y a-t-il un moyen de le contourner?

Informations complémentaires:

Nous avons testé ce comportement avec (toujours la dernière version)

  • Windows 7 + Office 2016 - une mauvaise conduite survient
  • Windows 10 + Office 2016 - une mauvaise conduite survient

A également vérifié l'ancienne version Office pour s'assurer qu'il s'agissait bien d'une chose Office 2016.

  • Windows 8 + Office 2013 - ça n'arrive pas
  • Windows 7 + Office 2010 - ça n'arrive pas
  • Windows 10 + Office 2010 - ça n'arrive pas
  • Windows 10 + Office 2013 - ça n'arrive pas
10
Rand Random

Je m'excuse si je réitère toutes mes explications, mais comme je trouve cette question très complexe, j'ai donc essayé de faire en sorte que cela ait un sens pour les lecteurs:

Bien que l’on ne sache pas s’il s’agit ou non d’un bogue, nous pouvons le forcer à s’ouvrir dans la "même" instance en utilisant le protocole DDE (Dynamic Data Exchange) en créant un message DDE au lieu de l’argument difficile "% 1 "pointant vers le fichier que cette instance doit ouvrir lors de l’exécution du fichier. (Bien que DDE soit utilisé même avec l'argument difficile).

Le message DDE, dans ce cas, est utilisé pour indiquer au programme d'ouvrir un fichier. En fait, chaque fichier exécuté crée une nouvelle instance à chaque fois. Mais lorsque le protocole DDE est utilisé, il vérifie d’abord si une instance est déjà créée et, si tel est le cas, il relaie le message DDE à la première instance trouvée et se ferme, donnant ainsi l’illusion que tous les fichiers s’ouvrent dans une seule instance car elle est instantanée.

Spéculations

La question des fichiers s’ouvrant dans plusieurs instances est probablement liée au nombre de fois où une seule instance a déjà été chargée lorsqu’une autre instance est appelée. La tendance entre la différence de temps d'exécution d'une première et d'une seconde instance est d'autant plus grande que le temps entre les exécutions augmente, qu'elle tend à ne générer qu'une seule instance et qu'elle diminue à mesure qu'elle diminue. Cela suggère que la première instance doit être chargée ou "prête" pour ouvrir un nouveau fichier dans la même instance si un autre fichier est exécuté, sinon, il doit ouvrir le fichier avec lui-même.

Il semble que lorsque le chemin du fichier est utilisé comme argument du programme, il semble suivre cette tendance pour seulement:

  • Word 2016
  • Excel 2016

Lorsqu'elle est utilisée comme argument pour créer des instances au-delà de la première instance si la première est prête (ou si les non-premiers voient qu'elle est prête), l'instance non-première semble pouvoir relayer l'argument sous forme de message DDE vers la première.

Cependant, si nous exécutons le programme et utilisons un message DDE pour ouvrir le fichier, il semble suivre immédiatement le protocole DDE, que la première instance soit prête ou non à accepter le message DDE via un argument. Que la première instance soit ou non prête dépend probablement de savoir si la première instance est considérée comme prête et si elle ne le fait pas, elle n'enverra pas le message DDE à la première, ce qui semble ne se produire que lorsqu'elle s'ouvre via un argument. . La spéculation du non-premier voyant le premier comme non "prêt" ou "non-existant" est suggérée par le fait que les messages DDE (des non-premiers) sont acceptés par le premier quand: le non-premier n'est pas exécuté via une concaténation d'arguments "% 1"; et il est dit d'ouvrir via un message DDE.

En tant que tel, ma spéculation est la suivante: le code de ces applications utilise une méthode obscure pour déterminer si une autre instance est "prête" et, dans l'affirmative, utiliserait alors le protocole DDE lorsqu'un argument est utilisé. Cela semble utiliser une méthode différente de celle qui consiste à recevoir le protocole DDE pour déterminer s'il convient de l'envoyer à une autre instance. Il semblerait en effet que le pseudocode soit:

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

Il n'y a aucun moyen de dire s'il s'agit d'un bogue ou s'il était censé être obscur pour une raison sans que les programmeurs nous informent.

La résolution

Nous voulons ajuster l’exécution de certaines extensions de fichier pour ne plus envoyer en argument le chemin du fichier ("% 1") du fichier en cours d’exécution, mais plutôt indiquer au programme en cours d’exécution le contenu du message DDE, dont contient une demande pour ouvrir un fichier, qui le relèvera à une instance déjà existante s'il existe et s'il ne l'utilise pas lui-même. Ce qui spéculativement, contournera les exigences obscures de ces applications pour qu'une autre instance soit considérée comme "prête" si un argument du chemin du fichier est utilisé.

Ce sont toutes des extensions de fichier corrélées à des clés de classe qui doivent être remplacées par x:

Pour mot

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

Pour 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

* Les extensions de fichiers les plus importantes/communes qui devraient être effectuées au minimum. Subjectif.

† Les extensions de fichier les plus importantes/communes secondaires qui doivent être effectuées au minimum. Subjectif.

Ces listes peuvent être répliquées via la ligne de commande: assoc | findstr Word en remplaçant Word par le nom abrégé officiel (respectant la casse).

Tout ce que vous avez la possibilité de faire si vous le jugez nécessaire. Si vous voulez en faire plus, vous voudrez peut-être suivre les étapes optionnelles que je vais fournir, ce qui devrait réduire le travail nécessaire.

Vous devez suivre les instructions suivantes pour chaque clé de registre ci-dessous en remplaçant la x par la ou les classes correspondantes de votre choix:

  • HKEY_CLASSES_ROOT\x\Shell\Open
  • HKEY_CLASSES_ROOT\x\Shell\OpenAsReadOnly

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

Une fois encore, la clé OpenAsReadOnly est optionnelle. Elle sera prête lorsque le fichier sera exécuté de manière à être en lecture seule.

Une petite précaution - une sauvegarde

Pour mieux vous rappeler quelles étaient les valeurs du registre avant la modification, vous souhaiterez peut-être cliquer avec le bouton droit de la souris sur la branche HKEY_CLASSES_ROOT et, dans le menu contextuel, cliquer sur "Exporter" pour enregistrer le fichier d'enregistrement dans un emplacement. Dans le cas où Doc Brown dit "Nous devons revenir en arrière", vous pouvez simplement importer la clé de registre en l'exécutant et en suivant les instructions.

Alternativement, vous pouvez également exécuter ceci afin de vous rappeler quelles étaient les valeurs command et les noms de classe afin de corriger de petites erreurs avec:

assoc>>fileexts.txt qui peut être filtré avec type fileexts.txt | findstr Word

ftype>>classnames.txt qui peut être filtré avec type classnames.txt | findstr Word

Instructions

Celles-ci doivent être suivies pour chaque valeur clé indiquée ci-dessus, comme vous le souhaitez.

Entrez dans votre éditeur de registre préféré ou dans regedit et accédez au cours que vous souhaitez modifier.

Entrez dans la clé appelée command, cliquez-droit sur la valeur (Default), puis cliquez sur "Modifier" dans le menu contextuel.

Actuellement défini devrait être ce qui a été exécuté par ftype | findstr Word

Modifiez-le pour supprimer les arguments directs à la fin de la valeur, , y compris l'espace, pour devenir:

  • "C:\Program Files\Microsoft Office\Root\Office16\Excel.EXE"
    (Pour Excel 64 bits)
  • "C:\Program Files\Microsoft Office\Root\Office16\WINWORD.EXE"
    (Pour Word 64 bits)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\WINWORD.EXE"
    (Pour Word 32 bits)
  • "C:\Program Files (x86)\Microsoft Office\Root\Office16\Excel.EXE"
    (Pour Excel 32 bits)

Entrez dans la clé appelée ddeexec (si elle n'existe pas, créez la clé) qui serait à côté de la clé command, cliquez avec le bouton droit sur la valeur (Default) et cliquez sur "Modifier" dans le menu contextuel, puis définissez la valeur comme suit:

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

Sous ddeexec, créez une nouvelle clé appelée topic (si elle n’existe pas), cliquez avec le bouton droit de la souris sur la valeur (Default), cliquez sur "Modifier" dans le menu contextuel, puis définissez la valeur sur system (si ce n’est déjà fait).

Après les modifications, vous devrez peut-être actualiser Shell32.dll en l'exécutant avec une invite de commande ou un shell après la création des modifications suivantes dans le registre:

regsvr32 /i Shell32.dll

Cela a été testé sur Windows 10 Office 2016 version 16.0.8625.2127.

Raccourci alternatif

Vous pouvez également accéder à la clé des extensions de fichier (telle que HKEY_CLASSES_ROOT\.xlsx) et modifier la valeur "(valeur par défaut)" en une classe unique. Cette approche, si elle est suivie, peut pointer plusieurs extensions de fichier vers la même valeur de classe (telle que Excel.Sheet.12). que vous ne devez modifier cette classe qu’une fois avec le message DDE. Si vous faites cela, vous devez également renommer toutes les répétitions du nom de la classe à l'intérieur de cette branche du registre. Cependant, cette façon de faire n'est pas recommandée car cela pourrait facilement casser et devrait être effectuée si vous deviez effectuer toutes les extensions de fichier pour gagner du temps.

Notes de bas de page:

L'argument /o est un argument pour les URL. La perte de cette fonctionnalité n'est donc pas un problème car elle est rarement transmise. Cependant, si vous le souhaitez, vous pouvez essayer de laisser cette partie de l'argument activée lors du réglage des valeurs (Default).

J'envisage de faire de ce wiki une communauté, car il est très spéculatif et également inachevé (si Word et Excel n'étaient pas les seuls). S'il vous plaît commenter un avis à ce sujet.

7
El8dN8

En plus de l'excellente réponse de @ El8tedN8te, je remarque que pour Excel, il n'est pas nécessaire de modifier la clé de registre ddeexec.

Il suffit de définir la valeur de l'élément (Default) sur:

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

Ceci par mes tests garantit qu'une seule instance d'Excel est exécutée.

1
harrymc