12
votes

PowerShell - Redirection de la liaison Assembly introuvable dans le fichier de configuration de l'application

Vous avez un problème ici ...

J'ai une cmdlet PowerShell qui fonctionne lors de l'exécution en mode 32 bits et échoue en mode 64 bits. La question est de savoir ce que la cause est et comment elle peut être corrigée. P>

Situation H1>

PowerShell Cmdlet qui fait référence à "OutlookHelper.co.dll". La plus récente version est 2.0.0.0 La cmdlet utilise également la journalisation et les références 'Logging.dll'.
Logging.dll Références également 'OutlookHelper.common.dll', a été compilée uniquement contre la version 1.0.0.0. P>

Comment je l'ai fait fonctionner, cela fonctionne partiellement h1>

Utilisation d'une redirection de liaison de montage Dans le fichier de configuration de l'application de PowerShell: P>

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\testuser> gc C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe.Config
<?xml version="1.0"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0.30319"/>
        <supportedRuntime version="v2.0.50727"/>
    </startup>
</configuration>
PS C:\Users\testuser>

2 commentaires

Où sont les DLL sur le disque? Sont-ils présents dans C: /Windows/system32/windowspowershell/v1.0 / ou ailleurs?


ddls comme psevents.dll, pspluginwkr.dll, pspluginwkr-v3.dll, pwrysg.dll, pwshsip.dll est présent dans le dossier System32 et dans le dossier SYSWOW64. Le contenu du fichier n'est pas le même cependant.


3 Réponses :


3
votes

sur une machine 64 bits Il existe deux fichiers de configuration: xxx

avez-vous modifié les deux sur la machine 64 bits?

sur 64 bits versions de Windows. Les processus 32 bits (comme Notepad ++) sont redirigés de manière transparente à partir de C: \ Windows \ System32 à C: \ Windows \ SYSWOW64 par le système d'exploitation.

Vous devrez vous assurer de modifier les deux fichiers à l'aide d'un fichier 64 bits. Editeur de texte comme le NotePad.exe intégré. Cela vous garantira que vous ne souffrez pas de ce problème subtil, qui peut causer une confusion.


9 commentaires

Oui, j'ai essayé, essayé d'éditer l'un des deux, puis le système d'exploitation change / synchronise les modifications apportées à l'autre fichier. J'ai donc essayé de changer celui-ci dans le système32 -> n'a pas fonctionné. Essayé de changer celui-ci à SYSWOW64. J'ai essayé de supprimer les deux, puis de tester 2 scénario d'où j'ajouterais le fichier dans la System32 dans le premier scénario et ajouterais ensuite ajouter le fichier dans le dossier SYSWOW64 -> N'a pas fonctionné.


Pouvez-vous exécuter ce qui suit dans PowerShell and PowerShell (X86) et dites-moi la sortie dans chaque: ([xml] (GC $ ([[System.appdomain] :: courantDomain.setupinformation.configu Rationfile)))). Configuration uration. Runtime.ASSE Mblblybinding.Dependen Tassembly.AssemblyId Identité


Merci pour votre commentaire Dan! J'ai mis à jour ma question avec les informations que vous avez demandées. On dirait que les 64 bits manquent quelque chose.


Bonjour Mathijsuitmegen, pouvez-vous exécuter GC C: Windows \ System32 \ WindowsPowershell \ v1.0 \ PowerShell.exe.co NFIG dans une console de PowerShell 64 bits et postez la sortie. Merci


Vous êtes sur quelque chose de dan! PowerShell ne lit pas le fichier entier. Lorsque je déverroue un cmd.exe et que je fais un "type" dans le même fichier, tout le contenu du fichier est affiché (y compris l'élément "Runtime").


Bonjour Mathijsuitmegen, pouvez-vous ouvrir C: \ Windows \ System32 \ windowspowershell \ v1.0 \ powershell.exe.co nfig dans le bloc-notes [pas d'autre éditeur de texte et assurez-vous qu'il est C: \ Windows \ System32 \ NotePad.exe ( Les programmes 32 bits ne peuvent pas "réellement accéder" des fichiers à l'intérieur C: \ Windows \ System32 Même s'ils semblent être capables de le faire)]. Le fichier apparaît-il que vous attendez?


J'ai ouvert le fichier dans NotePad.exe comme vous l'avez mentionné, il manque les paramètres «Runtime».


Avez-vous essayé d'éditer le fichier dans le Bloc-notes pour ajouter les paramètres d'exécution, puis réessaisant.


Laissez-nous Continuez cette discussion en chat .



10
votes

Non 100% lié au problème de 32/64 bits, cependant, si une personne s'intéresse à Solution de redirection de l'Assemblée forte> Assemblée Veuillez regarder ici Assemblage de configuration PowerShell Rediriger .

Vous pouvez faire une redirection de l'assemblage personnalisé à l'aide de code PowerShell comme P>

$FSharpCore = [reflection.assembly]::LoadFrom($PSScriptRoot + "\bin\LIBRARY\FSharp.Core.dll") 

$OnAssemblyResolve = [System.ResolveEventHandler] {
  param($sender, $e)

  # from:FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  # to:  FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  if ($e.Name -eq "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") { return $FSharpCore }

  foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies())
  {
    if ($a.FullName -eq $e.Name)
    {
      return $a
    }
  }
  return $null
}

[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)


1 commentaires

Désolé, le projet a été supprimé.



7
votes

Basé sur la réponse extrêmement utile de @ Davidpodhola, j'ai commencé à mettre quelque chose comme celui-ci dans mes fichiers de module PSM1. Si vos nouveaux assemblages sont déjà chargés (par importateur-module par exemple), cela devrait fonctionner: xxx

mise à jour: PowerShell semble avoir un bogue où l'enregistrement simplement l'enregistrement d'un assembly résolve ScriptBlock peut provoquer une imperpaireFlowException lors de l'appel des commandes telles que Out-GridView. J'ai mis à jour le code pour utiliser une version compilée avec ADD-Type qui semble résoudre le problème.


4 commentaires

Cela fonctionne très bien, mais comment évitez-vous les débordements de la pile lors de la sortie? Si je quitte le gestionnaire AssemblyResolve dans, PowerShell se bloque à la sortie. Ce qui suit l'empêche [System.AppDomain] :: actuelDomain.remove_assemblyResolve ($ sur AssemblyResolve) Mais cela enfreint l'encapsulation et signifie que l'utilisateur de l'Assemblée doit savoir désenregistrer le gestionnaire d'événements. J'ai essayé de le faire dans les manutentionnaires de décharge et de sortie d'AppDomain, mais sans succès.


Vous savez que j'avais parfois obtenu cette exception et j'ai supposé que c'était quelque chose d'enterré dans tout le code INTEROP que j'écrivais car il écraserait le processus. Malheureusement, je pense que le problème est plus profond que de simplement retirer le résolveur, car sur ma machine, je peux reproduire 100% en enregistrant simplement un résolveur qui ne fait rien et un appel à Out-GridView. Les Docs pour AssemblyResolve indiquent que si un gestionnaire de résolution conduit à AppDomain.Load ou Assembly.Load Mettez appelé Vous pouvez obtenir une stackoverflowException, mais je ne sais pas comment cela peut arriver avec ce petit code:


$ OnassemblblyResolve = [System.ResMeventhandler] {param ($ Sender, $ resolteventargs) hébergement écriture - Vert "essayer de résoudre quelque chose" renvoyer NULL; } [System.appdomain] :: ActualDomain.add_assemblayResolve ($ onass EmblyResolve); Ça va écraser PowerShell avec une StackoverFlowException Essayez {1..10 | Out-GridView} Catch {# Ça ne sera pas frappé}


@ben, j'ai eu un fil de fil avec quelqu'un en interne à la SEP et a suggéré d'utiliser un résolveur compilé de type ADD-Type afin d'éviter le débordement de la pile. Je ne peux pas dire que je suis exactement sûr que cela fait une différence, mais cela semble fonctionner. Je vais mettre à jour mon exemple ...