Hololens HttpWebRequest SendFailure IL2CPP advapi32.dll

Hi everybody,

I’m trying to access data on a TheThingsNetwork server via HttpWebRequest. All works fine in a simple C# command line application.

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlIoTSensorData);
                request.AutomaticDecompression = DecompressionMethods.GZip;
                request.Headers["Authorization"] = "key ttn-account-v2.mqAaM7T6m58sqvdrgvqerp7h3nuO0LiX49XdH-CZsQ";

(I altered the key posted here obviously)
When I use the same code in Unity, I get: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure

After some Googling, I found a workaround, which is to completely ignore the certificates issues:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
           delegate (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                   System.Security.Cryptography.X509Certificates.X509Chain chain,
                                   System.Net.Security.SslPolicyErrors sslPolicyErrors)
           {
               return true; // **** Always accept
           };

Since I’m building for Hololens (UWP), I’m stuck with .NET Core, which doens’t have a ServicePointManager class. So I switched my scripting backend to IL2CPP.

All works great in Unity editor. I can build my project and put it on my Hololens via Visual Studio. But on the Hololens, at runtime, I get an error message: unable to load dll advapi32.dll.

So any pointers on this?

Is there a way to use HTTPWebRequest on the Hololens without the ugly ServicePointManager solution?

Is there a fix for the missing advapi32.dll error?

Thanks in advance,

Boi

Hey, this is most likely a bug in our class libraries. Can we get a bug report?

Also, while this is not answering your question directly, is there any reason you don’t use UnityWebRequest instead?

Thank you for your answer. I’m reporting the bug right now.

Is there any reason why UnityWebRequest would work in my situation? Seeing I got a authentication SendFailure? What’s the difference under the hood?

Kind regards,

Boi

You know what, I tried it like this:

   UnityWebRequest www = UnityWebRequest.Get(urlIoTSensorData);
            www.SetRequestHeader("Authorization", "key ttn-account-v2.mqAaM7T6m588UKxrZHzp7h3nuO49XdH-CZsQ");
            yield return www.Send();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
                guiTextForFeedback.text += "\n" + www.error;
            }
            else
            {
                dataString = www.downloadHandler.text;
            }

Now it works. Any thoughts on this?

Anyway now I can use my Hololens to look at a Vuforia marker and display some IoT sensor data (just temperature and humidity for now), that I’m fetching via The Things Network.

Thanks for your assistance.

Regards,
Boi

Any update on this issue? I noticed that it’s been flagged as a bug over here too. https://issuetracker.unity3d.com/issues/unable-to-load-dll-advapi32-dot-dll-when-running-an-app-on-hololens-at-runtime-after-httpwebrequest

Sorry man, no updates. Good luck.

Got the same issue with an API generated from Swagger Codegen (so not easy to swap out everything for UnityWebRequest).

I generated using

-l csharp -t swagger-templates/csharp --additional-properties targetFramework=v3.5

and had to jump a few hoops in order to get it running in Unity editor and runnable on HoloLens (IL2CPP e.g. is needed). Now everything looks good until I do a API-call and get the error that advapi32.dll is not available.

Is there a fix for the missing advapi32.dll error?

I’m also getting issues with advapi32.dll being missing. Tried the latest release, cause the tracker claims the issue is fixed, but no avail. Not using httpclient tho.

Well, advapi32.dll is not available on UWP. That’s why you get that error. The thing that was fixed was to make HttpClient to not use advapi32.dll.

What is throwing that exception for you?

I was digging into it yesterday. Seems like it’s related to getting the current time, and for some reason falls back to that dll to get it the local time zone from the registry.

I can repro this by just trying to get the current DateTime.Now in an IL2CPP Build.

Which Unity version are you on? Does this exception actually get propagated to your code? Or is it thrown/caught inside mscorlib? Keep in mind that we have one mscorlib.dll for all platforms, and different platforms have different paths to acquire time zone. I believe it first tries registry because that gives the most information for regular Windows desktop applications, and then if that fails, tries using Windows 8+ functions, which actually work for UWP.

2018.1.9f1 Can’t use latest version of unity bc of object selector bug.

Does this exception actually get propagated to your code? Or is it thrown/caught inside mscorlib?

Not sure what you mean here. All I know is that DateTime.Now works for .NET back end but not IL2CPP. Throws a C++ exception about missing the advapi32.dll cause it’s trying to get the local timezone from the registry.

There are you types of exceptions: ones that are caught (first chance) and ones that are not (second chance). Depending on your debugger configuration, it might break on both, only the second chance or none. In cases the debugger breaks on a first chance exception, you are able to continue past it. If you don’t want the debugger to stop on every exception that’s thrown, you can change that in the debugger exception settings.

I strongly believe that you’re hitting a first chance exception.

Read this:

https://docs.microsoft.com/en-us/security-risk-detection/concepts/first-chance-exception

(Still Stephen, just logged into my personal account)
Just to give you a bit of background, the application is trying to unzip a file, and the zip method tries to set the last accessed time. This is where it fails and doesn’t finish unzipping the file. Works on .NET scripting backend but not IL2CPP bc it’s trying to get the time incorrectly.

I just made a project in Unity 2018.1, added this script to a gameobject:

using System;
using UnityEngine;

public class Script : MonoBehaviour
{
    void Start()
    {
        Debug.Log(DateTime.Now);
    }
}

And built it to UWP/IL2CPP. Seems to work fine:

2018-08-28 09:07:33
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
Script:Start()
(Filename: C:\buildslave\unity\build\Runtime/Export/Debug.bindings.h Line: 43

If you’re facing non-first chance exceptions, it could be something project related or a bad callstack causing confusion over what’s actually throwing. In that case, could we get a bug report?

Using the latest version of Unity seems to have fixed this for me.

What version of Unity do you use? I still have the problem on Unity 2018.2.6f1.

“Unable to load DLL ‘advapi32.dll’: The specified module could not be found.”

Call stack:

    GameAssembly.dll!il2cpp::vm::Exception::Raise(Il2CppException * ex, Il2CppSequencePoint * seqPoint, MethodInfo * lastManagedFrame) Ligne 61    C++
    GameAssembly.dll!il2cpp::vm::PlatformInvoke::Resolve(const PInvokeArguments & pinvokeArgs) Ligne 57    C++
    GameAssembly.dll!il2cpp_codegen_resolve_pinvoke<int (__cdecl*)(__int64,wchar_t *,__int64,int,__int64 *),13,13>(const wchar_t[13] & nativeDynamicLibrary, const char[13] & entryPoint, Il2CppCallConvention callingConvention, Il2CppCharSet charSet, int parameterSize, bool isNoMangle) Ligne 515    C++
    GameAssembly.dll!Win32RegistryApi_RegOpenKeyEx_m3279997235(Il2CppObject * __this, __int64 ___keyBase0, String_t * ___keyName1, __int64 ___reserved2, int ___access3, __int64 * ___keyHandle4, const MethodInfo * method) Ligne 24661    C++
    GameAssembly.dll!Win32RegistryApi_OpenSubKey_m705243201(Win32RegistryApi_t3010839375 * __this, RegistryKey_t4211574351 * ___rkey0, String_t * ___keyName1, bool ___writable2, const MethodInfo * method) Ligne 25684    C++
    GameAssembly.dll!InterfaceFuncInvoker3<RegistryKey_t4211574351 *,RegistryKey_t4211574351 *,String_t *,bool>::Invoke(unsigned int slot, Il2CppClass * declaringInterface, Il2CppObject * obj, RegistryKey_t4211574351 * p1, String_t * p2, bool p3) Ligne 196    C++
    GameAssembly.dll!RegistryKey_OpenSubKey_m1748826992(RegistryKey_t4211574351 * __this, String_t * ___name0, bool ___writable1, const MethodInfo * method) Ligne 23268    C++
    GameAssembly.dll!TimeZoneInfo_get_LocalZoneKey_m820481003(Il2CppObject * __this, const MethodInfo * method) Ligne 28010    C++
    GameAssembly.dll!TimeZoneInfo_CreateLocal_m701291163(Il2CppObject * __this, const MethodInfo * method) Ligne 27027    C++
    GameAssembly.dll!TimeZoneInfo_get_Local_m2495540097(Il2CppObject * __this, const MethodInfo * method) Ligne 26667    C++
    GameAssembly.dll!TimeZoneInfo_GetDateTimeNowUtcOffsetFromUtc_m3893949862(Il2CppObject * __this, DateTime_t3738529785 ___time0, bool * ___isAmbiguousLocalDst1, const MethodInfo * method) Ligne 28541    C++
    GameAssembly.dll!DateTime_get_Now_m1277138875(Il2CppObject * __this, const MethodInfo * method) Ligne 36457    C++
    GameAssembly.dll!DPUtils_get_LocalDateShortString_m4123045169(Il2CppObject * __this, const MethodInfo * method) Ligne 38933    C++
    GameAssembly.dll!DPManager_Awake_m697199593(DPManager_t1997106759 * __this, const MethodInfo * method) Ligne 39994    C++
    GameAssembly.dll!RuntimeInvoker_Void_t1185182177(void(*)() methodPointer, const MethodInfo * methodMetadata, void * obj, void * * args) Ligne 61585    C++
    GameAssembly.dll!il2cpp::vm::Runtime::Invoke(const MethodInfo * method, void * obj, void * * params, Il2CppException * * exc) Ligne 513    C++
    GameAssembly.dll!il2cpp_runtime_invoke(const MethodInfo * method, void * obj, void * * params, Il2CppException * * exc) Ligne 958    C++

It is trying to access the registry to get the local time zone.

It does, but after that fails, it will fallback to using alternate methods. Just continue through that exception (or disable breaking on every exception thrown).

I too am getting this error with IL2CPP under unity 2018.3.7f1
The exception is thrown at code:

this.time = DateTime.Now;

Exception: “System.DllNotFoundException: Unable to load DLL ‘advapi32.dll’: The specified module could not be found.”
is there some sort of work around?

Yes, ignore the exception.