2

Scenario and problematic code

I'm calling a public method within a custom assembly library after creating a new instance of the public class encapsulating said method.

$openApiDocumentGenerator = New-Object Microsoft.OpenApi.CSharpComment.Reader.OpenApiDocumentGenerator
$openApiDocumentGenerator.GenerateSerializedOpenApiDocuments( $VisualStudioXmlDocument, $AssemblyPaths, $OpenApiSpecVersion, $OpenApiFormat, $ConfigurationXmlDocument)

I've loaded my custom assembly and dependencies by doing the following,

Add-Type -AssemblyName "System.Web"
Add-Type -AssemblyName "System.Xml.Linq"
Add-Type -Path $newtonsoftJsonAssemblyPath
Add-Type -Path $sharpYamlAssemblyPath
Add-Type -Path $microsoftOpenApiReadersAssemblyPath
Add-Type -Path $microsoftOpenApiAssemblyPath
Add-Type -Path $csharpCommentReaderAssemblyPath

Exception as a result of calling GenerateSerializedOpenApiDocuments method

System.Management.Automation.MethodInvocationException: Exception calling "GenerateSerializedOpenApiDocuments" with "5" argument(s): "Could not load file or assembly 'Microsoft.OpenApi.CSharpComment.Reader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified." ---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.OpenApi.CSharpComment.Reader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Activator.CreateInstance(String assemblyString, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
   at Microsoft.OpenApi.CSharpComment.Reader.AppDomainCreator`1..ctor()
   at Microsoft.OpenApi.CSharpComment.Reader.OpenApiDocumentGenerator.GenerateSerializedOpenApiDocuments(XDocument annotationXmlDocument, IList`1 contractAssemblyPaths, OpenApiSpecVersion openApiSpecVersion, OpenApiFormat openApiFormat, XDocument configurationXmlDocument)
   at CallSite.Target(Closure , CallSite , Object , XDocument , Object , Object , Object , XDocument )
   --- End of inner exception stack trace ---
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

What have I tried so far?

  1. Ensured the CLRVersion of PowerShell matches my custom assembly and dependencies, which are .Net Framework 4.6.2

    PS D:\> $psversiontable
    
    Name                           Value
    ----                           -----
    PSVersion                      5.1.15063.786
    PSEdition                      Desktop
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
    BuildVersion                   10.0.15063.786
    CLRVersion                     4.0.30319.42000
    WSManStackVersion              3.0
    PSRemotingProtocolVersion      2.3
    SerializationVersion           1.1.0.1
    
  2. Ensured my custom assembly (denoted by ++ below) is loaded along with all of its dependencies (denoted by -- below). To get the list of loaded assemblies, I leveraged [System.AppDomain]::CurrentDomain.GetAssemblies() just before the line of code that generates the exception above.

    {FullName=mscorlib; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=Microsoft.PowerShell.ConsoleHost; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    --{FullName=System; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=System.Core; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=System.Management.Automation; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    {FullName=Microsoft.Management.Infrastructure; Version= 1.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    {FullName=System.Management; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    {FullName=System.DirectoryServices; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    --{FullName=System.Xml; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=System.Numerics; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=System.Data; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=Anonymously Hosted DynamicMethods Assembly; Version= 0.0.0.0; Culture= neutral; PublicKeyToken= null}
    {FullName=Microsoft.PowerShell.Security; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    {FullName=System.Transactions; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    {FullName=System.Configuration; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    {FullName=Microsoft.Powershell.PSReadline; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    {FullName=Microsoft.CSharp; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    {FullName=Microsoft.PowerShell.Commands.Management; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    {FullName=System.Configuration.Install; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    {FullName=Microsoft.PowerShell.Commands.Utility; Version= 3.0.0.0; Culture= neutral; PublicKeyToken= 31bf3856ad364e35}
    --{FullName=Newtonsoft.Json; Version= 8.0.0.0; Culture= neutral; PublicKeyToken= 30ad4fe6b2a6aeed}
    --{FullName=SharpYaml; Version= 1.6.1.0; Culture= neutral; PublicKeyToken= 1ced8108e942bc02}
    --{FullName=Microsoft.OpenApi.Readers; Version= 1.0.0.0; Culture= neutral; PublicKeyToken= 3f5743946376f042}
    --{FullName=Microsoft.OpenApi; Version= 1.0.0.0; Culture= neutral; PublicKeyToken= 3f5743946376f042}
    ++{FullName=Microsoft.OpenApi.CSharpComment.Reader; Version= 1.0.0.0; Culture= neutral; PublicKeyToken= null}
    --{FullName=System.Xml.Linq; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b77a5c561934e089}
    --{FullName=System.Web; Version= 4.0.0.0; Culture= neutral; PublicKeyToken= b03f5f7f11d50a3a}
    

What can the issue be? Am I invoking the method incorrectly?

4
  • The system cannot find the file specified. Did you read your own error? Commented Jan 9, 2018 at 4:44
  • @TheIncorrigible1 Yes, I read the error. All Add-Type functions passed and then when calling the instance method mentioned, I get that error. PowerShell seems to be reloading the type, but I haven't asked it to, but I have pre-loaded the type... Any helpful suggestions? Commented Jan 9, 2018 at 8:02
  • @ScottLin try to unblock your DLL files as follows. Right click on the DLL, select Properties and click unblock in the general tab. Commented Jan 9, 2018 at 10:01
  • @rufer7 There is no unblock option on the general tab of Properties for the assembly files. Commented Jan 9, 2018 at 17:54

1 Answer 1

2

It turns out, the library I was invoking created a new app domain and then tried to the load assemblies I passed along. However, the new app domain base path was set to the location of PowerShell.exe on the machine, so the paths did not resolve correctly since the paths were relative to the script's app domain base path.

The solution in my case was to set the base path before invoking the library, and then revert back the the original base path after the library returned control to my script.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.