Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing DLL Exception in F# Script loading from Azure CosmosDb

Tags:

f#

azure

I'm trying to test some different queries in an F# script file against my Azure CosmosDb, but I'm getting an error regarding a missing DLL when I try to execute a query itself.

I'm loading the Documents.Client.dll:

#r "../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll"
open Microsoft.Azure.Documents
open Microsoft.Azure.Documents.Client
open Microsoft.Azure.Documents.Linq

But when I execute a query:

Seq.toList <| query {
            //some query that I copy & pasted from a working file
        }

I get this error:

System.AggregateException: One or more errors occurred. ---> System.DllNotFoundException: Unable to load DLL 'Microsoft.Azure.Documents.ServiceInterop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at Microsoft.Azure.Documents.ServiceInteropWrapper.CreateServiceProvider(String configJsonString, IntPtr& serviceProvider)
   at Microsoft.Azure.Documents.Query.QueryPartitionProvider.Initialize()
   at Microsoft.Azure.Documents.Query.QueryPartitionProvider.GetPartitionedQueryExecutionInfoInternal(SqlQuerySpec querySpec, PartitionKeyDefinition partitionKeyDefinition, Boolean requireFormattableOrderByQuery, Boolean isContinuationExpected)
   at Microsoft.Azure.Documents.Query.DocumentQueryExecutionContextBase.<GetPartitionedQueryExecutionInfoAsync>d__0.MoveNext()

(there is more in the stack trace - this is just the top of it).

I can't find the ServiceInterop dll anywhere - it's not referenced in any projects or in my packages folder, and it's not a nuget reference. I'm not sure what I could be missing to only get this error in F# Interactive.

Update

Following the advice in the comments from @tomislav-markovski, I changed the version of Microsoft.Azure.DocumentDB to 1.13.2. This does create the ServiceInterop dll in the package folder, but now running my query in F# interactive gives this output:

--> Referenced 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll' (file may be locked by F# Interactive process)


Script.fsx(5,1): error FS0229: Error opening binary file 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': c:\VSTS\MyApplication\../packages/Micro
soft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll: bad cli header, rva 0


Script.fsx(5,1): error FS3160: Problem reading assembly 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': Exception of type 'Microsoft.FSharp.Compiler.ErrorLogger+
StopProcessingExn' was thrown.

The "File may be locked" error seems like it's important, but I closed & reopened VSCode to make sure that instance of F# Interactive wasn't holding on to anything. I am referencing the Service Interop file:

#r "../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll"

If I remove this, the above errors go away... and I go back to the query itself crashing because of the missing DLL.

Update 2

I've tried a few additional things:

  1. Absolute instead of relative pathing to the Client.dll. This results in the "missing service interop dll" error.
  2. Absolute instead of relative pathing to the 'ServiceInterop.dll'. This results in the "error opening binary file" error.
  3. Using #I to load the DLL with easier pathing:

    #I "../packages/Microsoft.Azure.DocumentDB/lib/net45/"

    #r "Microsoft.Azure.Documents.Client.dll"

    Results in the same "missing ServiceInterop.dll" error.

  4. Simplifying the query:

    Seq.toList <| query { for t in client.CreateDocumentQuery( documentCollectionUri()) do select t }

This resulted in the same "missing ServiceInterop.dll" error. 5. Using FeedOptions with "Enable Cross Partiiton Query" on:

let feedOptions = FeedOptions()
feedOptions.EnableCrossPartitionQuery <- true
feedOptions.MaxItemCount <- 3 |> System.Nullable

Seq.toList <| query {
            for t in client.CreateDocumentQuery( documentCollectionUri(), feedOptions ) do
            select t
}

As you can see, I also tried setting the max item count. Both of these gave the same "missing ServiceInterop.dll" error.

like image 581
Max Avatar asked Jul 16 '17 17:07

Max


Video Answer


1 Answers

The closest thing to a solution for this that I was able to find was to add the location of the ServiceInterop.dll to the Path environment variable for the duration of the FSI session, something like so:

open System
open System.IO

// get existing contents of path env var
let path = Environment.GetEnvironmentVariable("Path") 

// get location where nuget puts the service interop dll
let serviceInteropDir = @C:\User\<USERNAME>\.nuget\packages\microsoft.azure.documentdb.core\1.9.1\runtimes\win\native"

// add service interop location to the end of the path
let newPath = path + ";" + serviceInteropDir

// update the path env var with the new path
Environment.SetEnvironmentVariable("Path", newPath)

NOTE: Notice I am using version 1.9.1 of the DocumentDB.Core package. There seems to be a strong naming problem with the 1.10.0 version of the DocumentDB.Core package, so avoid that version until a fix is released or a workaround is found.

like image 109
lambdakris Avatar answered Sep 30 '22 21:09

lambdakris