Azure / Azure/azure-functions-host

Support registry-free use of COM DLL's in Azure C# functions

Open
#2,283 10 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 12h
Merged PRs (30d)
38

Description

Azure Function C# script should load specified COM DLL and provide better diagnostics.

We are attempting to make use of existing C++ COM code in a DLL from an Azure C# function. We began building a C# Azure project in Visual Studio 2017 but found that the tooling would not let us select the manifest file which specifies the details for side-by-side registry-free use of COM DLL's.
We posted to the forum where it was suggested we try using a C# script created through the portal, as discussed here and represented by this ticket.

This ticket is for the portal-based scenario. If we get this portal-based scenario working, we will open a different ticket for tooling in Visual Studio if appropriate.

We referred to multiple docs on Azure Functions. A reply to the post in the forum also pointed us to https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#Referencing custom assemblies which suggests

> Private assemblies should be uploaded in a bin folder in the function directory. Reference the assemblies using the file name, such as #r "MyAssembly.dll".
> ...
#### Investigative information

Please provide the following:

- Timestamp: January 8, 2018 10:31 CST "clientSessionStartDate": {
"iso": "2018-01-08T16:34:12.220Z",
"offset": 360,
"ticks": 1515429252220
- Function App version (1.0 or 2.0-beta):
- Function App name: fap3
https://fap3.azurewebsites.net/
- Function name(s) (as appropriate):
- Invocation ID:
- Region: Central US

#### Repro steps

Provide the steps required to reproduce the problem:

Step 1) Build a MFC-based COM server representative of a currently existing COM engineering package. Source for this can be provided. Ours is named MFCHeDemo.dll.
Step 1B) Ensure that the side-by-side manifest is correct and is embedded in the DLL as a resource.
Step 1C) Test the use of this COM C++/MFC-based DLL from Excel
Step 1D) Test the use of this COM C++/MFC-based DLL from a C# WinForms app. Unregister the DLL. Test again using a side-by-side manifest for this C# app, and prove that it does actually use the DLL. Source for this app can also be provided.

Step 2) Create an Azure Function in the portal with an HTTP trigger. We are going to POST a json payload to this function. Code attached below.

Step 3) Upload the MFCHeDemo.dll to the function.

Step 4) Make a post to the azure function.
```json
{
"name": "Azure",
"tempInside":330,
"htcInside":10,
"tempOutside":270,
"htcOutside":40,
"wallThickness":0.1,
"wallK":0.7
}
```

#### Expected behavior

The C# script should find the DLL, load it and use it.
The HTTP trigger should respond with a reponse about heat flux.
In the alternative, diagnostics about failing to load the DLL, its dependencies should be available.

We've seen two outcomes.

#### Actual behavior
```
2018-01-08T17:34:39.935 Function started (Id=ffbd4721-1419-4229-80c6-a9e4fae0b752)
2018-01-08T17:34:40.105 Function compilation error
2018-01-08T17:34:40.105 run.csx(1,1): error CS0009: Metadata file 'D:\home\site\wwwroot\HttpTriggerCSharp1\bin\MFCHeDemo.dll' could not be opened -- PE image doesn't contain managed metadata.
2018-01-08T17:34:40.105 run.csx(27,13): error CS0246: The type or namespace name 'MFCHeDemo' could not be found (are you missing a using directive or an assembly reference?)
2018-01-08T17:34:40.105 run.csx(27,42): error CS0246: The type or namespace name 'MFCHeDemo' could not be found (are you missing a using directive or an assembly reference?)
2018-01-08T17:34:40.339 Exception while executing function: Functions.HttpTriggerCSharp1. Microsoft.Azure.WebJobs.Script: Script compilation failed.
2018-01-08T17:34:40.465 Function completed (Failure, Id=ffbd4721-1419-4229-80c6-a9e4fae0b752, Duration=523ms)

```

```
2018-01-08T16:58:06 No new trace in the past 11 min(s).
2018-01-08T16:59:03.367 Function started (Id=9bff7f10-3919-4378-b752-638833579e48)
2018-01-08T16:59:03.367 Function compilation error
2018-01-08T16:59:03.367 run.csx(1,1): warning AF006: The reference 'MFCHeDemo.dll' is invalid. If you are attempting to add a framework reference, please remove the '.dll' file extension.
2018-01-08T16:59:03.367 run.csx(1,1): error CS0006: Metadata file 'MFCHeDemo.dll' could not be found
2018-01-08T16:59:03.367 run.csx(27,13): error CS0246: The type or namespace name 'MFCHeDemo' could not be found (are you missing a using directive or an assembly reference?)
2018-01-08T16:59:03.367 run.csx(27,42): error CS0246: The type or namespace name 'MFCHeDemo' could not be found (are you missing a using directive or an assembly reference?)
2018-01-08T16:59:03.476 Exception while executing function: Functions.HttpTriggerCSharp1. Microsoft.Azure.WebJobs.Script: Script compilation failed.
2018-01-08T16:59:03.539 Function completed (Failure, Id=9bff7f10-3919-4378-b752-638833579e48, Duration=178ms)
````

#### Known workarounds

Provide a description of any known workarounds.

#### Related information

Provide any related information

* Programming language used
C++ with MFC. Fortran may eventually be used.
C# used in the Azure Function code.

* Links to source
* Bindings used

Source

```csharp
#r "MFCHeDemo.dll"

using System.Net;

public static async Task Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");

// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;

// Get request body
dynamic data = await req.Content.ReadAsAsync();

// Set name to query string or body data
name = name ?? data?.name;

double htcInside = data?.htcInside;
double tempInside = data?.tempInside;
double htcOutside = data?.htcOutside;
double tempOutside = data?.tempOutside;
double wallK = data?.wallThickness;
double wallThickness = data?.wallThickness;

MFCHeDemo.IHeCalc calc = new MFCHeDemo.HeCalc();
calc.HtcInside = htcInside;
calc.TempInside = tempInside;
calc.HtcOutside = htcOutside;
calc.TempOutside = tempOutside;
calc.WallK = wallK;
calc.WallThickness = wallThickness;
double heatFlux = calc.calcHeatFlux();

return req.CreateResponse(HttpStatusCode.OK, "flux is " + heatFlux);
}

```


Contributor guide

Open the contributing guide

Research direction

Start with the portal-based C# script, its #r "MFCHeDemo.dll" reference, and the HTTP trigger reproduction using the uploaded COM DLL. Reproduce the compilation errors, then verify that the function either loads the DLL and returns the heat-flux response or provides diagnostics explaining the missing DLL or dependencies.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, cpp, csharp
Domain
backend, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.