Bug 148857 - Handle is not initialized exception when bootstrapping with .Net (but not in .Net Framework)
Summary: Handle is not initialized exception when bootstrapping with .Net (but not in ...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: sdk (show other bugs)
Version:
(earliest affected)
7.3.1.3 release
Hardware: x86-64 (AMD64) Windows (All)
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
: 163072 (view as bug list)
Depends on:
Blocks: .NET
  Show dependency treegraph
 
Reported: 2022-04-29 16:27 UTC by Michele Locati
Modified: 2024-09-25 07:24 UTC (History)
9 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michele Locati 2022-04-29 16:27:20 UTC
Description:
Bootstrapping in .Net (tested with .Net 6) fails, whereas bootstrapping in .Net Framework (tested with .Net Framework 4.8) succeeds.


Consider this C# code:


static int Main()
{
    string programPath = GetProgramPath();

    System.Environment.SetEnvironmentVariable(
        "UNO_PATH",
        programPath,
        System.EnvironmentVariableTarget.Process
    );
    System.Environment.SetEnvironmentVariable(
        "URE_BOOTSTRAP",
        $"vnd.sun.star.pathname:{System.IO.Path.Combine(programPath, "fundamental.ini")}",
        System.EnvironmentVariableTarget.Process
    );
    System.Environment.SetEnvironmentVariable(
        "PATH",
        $"{programPath}{System.IO.Path.PathSeparator}{System.Environment.GetEnvironmentVariable("PATH")}",
        System.EnvironmentVariableTarget.Process
    );
    try
    {
        uno.util.Bootstrap.defaultBootstrap_InitialComponentContext();
        System.Console.Out.WriteLine("OK!");
        return 0;
    }
    catch (System.Exception x)
    {
        System.Console.Error.WriteLine(x.GetType().FullName);
        System.Console.Error.WriteLine(x.Message);
        System.Console.Error.WriteLine(x.StackTrace);
        return 1;
    }
}
static string GetProgramPath()
{
    var programPath = Microsoft.Win32.Registry.GetValue(
        Microsoft.Win32.Registry.LocalMachine.Name + @"\SOFTWARE\LibreOffice\UNO\InstallPath",
        "",
        null
    ) as string;
    if (string.IsNullOrEmpty(programPath))
    {
        throw new System.Exception("Failed to detect the program path");
    }
    return programPath;
}


When executed with .Net Framework 4.8 everything works just fine.

When executed with .Net 6 we have:

System.InvalidOperationException
Handle is not initialized.
   at System.Runtime.InteropServices.GCHandle.FromIntPtr(IntPtr value)
   at uno.util.to_cli<class com::sun::star::uno::XComponentContext>(Reference<com::sun::star::uno::XComponentContext>* x)
   at uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(String ini_file, IDictionaryEnumerator bootstrap_parameters)
   at uno.util.Bootstrap.defaultBootstrap_InitialComponentContext()
   at ConsoleDotNetFramework.Program.Main() in Program.cs:line 26


I tested it with LibreOffice 7.3.1.3 and with a fresh built of master (as of 2022-03-28): same results.
I also tested it in a Windows Sandbox: same results.



Steps to Reproduce:
1. Create a .Net (not .Net Framework) project
2. Add references to the DLLs that come with the SDK
3. Call uno.util.Bootstrap.defaultBootstrap_InitialComponentContext();

Actual Results:
defaultBootstrap_InitialComponentContext throws a System.InvalidOperationException exception:

Message: Handle is not initialized.
Stack trace:
   at System.Runtime.InteropServices.GCHandle.FromIntPtr(IntPtr value)
   at uno.util.to_cli<class com::sun::star::uno::XComponentContext>(Reference<com::sun::star::uno::XComponentContext>* x)
   at uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(String ini_file, IDictionaryEnumerator bootstrap_parameters)
   at uno.util.Bootstrap.defaultBootstrap_InitialComponentContext()


Expected Results:
defaultBootstrap_InitialComponentContext should return a unoidl.com.sun.star.uno.XComponentContext instance without throwing an exception.


Reproducible: Always


User Profile Reset: Yes



Additional Info:
I published a simple Visual Studio solution to showcase this: see https://github.com/mlocati/libreoffice-uno-dotnet

The .Net project fails, the .NetFramework project succeeds (with exactly the same code)
Comment 1 Vitaly 2022-11-13 11:09:18 UTC
Does anyone fixing this error or can say something about it?
Comment 2 Mike Kaganski 2023-05-30 07:41:55 UTC
I repro the problem both with net6, and netcoreapp3.1, using x64 platform. Also the same is I use 'uno.util.Bootstrap.bootstrap()' instead of 'uno.util.Bootstrap.defaultBootstrap_InitialComponentContext()'.

If you enable the mixed-mode debugging (allowing to debug native code), and put breakpoint to mediate_mapInterface (cppu/source/uno/lbmap.cxx), then the problem happens in the call to

        (*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr );

where VS reports that mapInterface points to {cli_uno.dll!Mapping_uno2cli}, but you can't step into it from the code editor, and when you use disassembly to step into, it looks like a no-op, instead of the expected Mapping_uno2cli from cli_ure/source/uno_bridge/cli_bridge.cxx. Trying to put breakpoints in the latter function (or anywhere in the file) is impossible (the debugger tells that "No executable code of the debugger's target code type is associated with this line ...").

Since the actually called code is a no-op, the ppOut will still contain a nullptr upon returning to mediate_mapInterface, and then the "Handle is not initialized" happens.

And here I get stuck, having no experience with all this machinery. Stephan, do you have an idea?
Comment 3 truer0man 2023-10-02 17:17:31 UTC
Bug is still exist in 7.6.2.1 version of SDK. I'm using .NET 7.
Comment 4 eins99 2024-01-12 13:39:16 UTC
I confirm this bug for

Version: 7.6.4.1 (X86_64) / LibreOffice Community
Build ID: e19e193f88cd6c0525a17fb7a176ed8e6a3e2aa1
CPU threads: 2; OS: Windows 10.0 Build 22621; UI render: Skia/Raster; VCL: win
Locale: de-DE (de_DE); UI: de-DE
Calc: threaded

Since the bug is not yet assigned to anybody since one and a half year it seems that the issue is not with high priority.
 
My question is if there is a workaround?
Comment 5 Mike Kaganski 2024-01-13 17:23:05 UTC
https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli

It seems to me, that the preferrable way to move forward would be to re-implement the cli assemblies in LibreOffice in C# or other language that doesn't have these limitations (if it is possible). Or to have a separate set of assemblies for .NET, as we have for .NET Framework.
Comment 6 Mike Kaganski 2024-01-13 17:32:03 UTC
FTR: running the DotNet6 config from the solution from comment 0, putting a breakpoint to loadEnv (cppu/source/uno/lbenv.cxx), when it gets called for "cli_uno", in the call to (*fpInit)( pEnv ), it will load the cli_uno.dll, which will load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll (seen in VS debugger's Output window); shortly after, an exception is thrown (no idea if it's important); and then, some assemblies for 4.0 will load, then unload; and finally, cli_uno.dll will unload. Neither before, nor after, it will be impossible to put a breakpoint to uno_initEnvironment in cli_ure/source/uno_bridge/cli_bridge.cxx.

When debugging DotNetFramework4.8 config, the uno_initEnvironment in cli_bridge.cxx will even be called directly, not from loadEnv.
Comment 7 eins99 2024-01-13 20:31:13 UTC
Since .NET Framework and .NET Core are now merged to .NET and will not see new development anymore, it would make sense to take in consideration to go this way also with LO. Otherwise coming releases of LO will not work with .NET.

How to deal with backward compatibility is another question.
Comment 8 liujian 2024-09-13 09:36:35 UTC
I the net8 error System. InvalidOperationException: "Handle is not initialized."
This is normal in the netframework

Faulty code
m_xContext = uno.util.Bootstrap.bootstrap();
Comment 9 Hossein 2024-09-21 07:49:59 UTC
The new .NET binding for cross platform .NET has just landed in master, and in order to use it, you need to compile LibreOffice from sources, or use daily builds: (or maybe wait for the next release)

https://dev-builds.libreoffice.org/daily/master/current.html

To get started, look into SDK examples:

https://git.libreoffice.org/core/+/refs/heads/master/odk/examples/DevelopersGuide/FirstSteps/FirstUnoContact/csharp/

https://git.libreoffice.org/core/+/refs/heads/master/odk/examples/DevelopersGuide/FirstSteps/FirstLoadComponent/csharp/

https://git.libreoffice.org/core/+/refs/heads/master/odk/examples/DevelopersGuide/FirstSteps/HelloTextTableShape/csharp/

https://git.libreoffice.org/core/+/refs/heads/master/odk/examples/dotnet/WriterDemo

Please take a look at this minimal code from FirstUnoContact example:

using System;
using com.sun.star.lang;
using com.sun.star.uno;
try
{
    XComponentContext xContext = NativeBootstrap.bootstrap();
    Console.WriteLine("Connected to a running office...");
    XMultiComponentFactory xMCF = xContext.getServiceManager();
    Console.WriteLine("Remote service manager is {0}", xMCF is null ? "not available" : "available");
    return 0;
}
catch (UnoException e)
{
    Console.Error.WriteLine(e.Message);
    return 1;
}

It uses NativeBootstrap.bootstrap().
Comment 10 Hossein 2024-09-21 07:50:12 UTC
*** Bug 163072 has been marked as a duplicate of this bug. ***
Comment 11 Michele Locati 2024-09-24 16:54:09 UTC
> Please take a look at this minimal code from FirstUnoContact example:

@Hossein How can we test the code? Is there an SDK containing the DLLs that can be added to a C# project?

I tried using the DLLs available in the cli directory installed by LibreOfficeDev_25.2.0.0.alpha0_Win_x86-64_sdk.msi (available at https://dev-builds.libreoffice.org/daily/master/Win-x86_64@tb77-TDF/2024-09-24_03.59.37 ), but I can't find any NativeBootstrap object (just the old uno.util.Bootstrap class in the cli_cppuhelper.dll file).
Comment 12 Mike Kaganski 2024-09-25 04:27:06 UTC
(In reply to Michele Locati from comment #11)

The sample's Makefile points to a nupkg in sdk/dotnet?
Comment 13 Michele Locati 2024-09-25 06:36:26 UTC
(In reply to Mike Kaganski from comment #12)
> (In reply to Michele Locati from comment #11)
> 
> The sample's Makefile points to a nupkg in sdk/dotnet?


The samples use this:

<PackageReference
    Include=\"$(LO_NUPKG_ID)\"
    Version=\"$(LO_NUPKG_VERSION)\"
/>

where LO_NUPKG_ID is LibreOffice.Bindings

But there's no nuget package with that ID at the moment: https://www.nuget.org/packages?q=LibreOffice.Bindings
Comment 14 Mike Kaganski 2024-09-25 06:43:37 UTC
(In reply to Michele Locati from comment #13)
> But there's no nuget package with that ID at the moment:
> https://www.nuget.org/packages?q=LibreOffice.Bindings

I mentioned the *exact* directory where that package is located. Note that it's a wrong idea that everything "nupkg" is about www.nuget.org: as MS explains [1],

> a NuGet package is a shareable unit of code, but does not require nor imply any particular means of sharing.

[1] https://learn.microsoft.com/en-us/nuget/what-is-nuget
Comment 15 Ritobroto Mukherjee 2024-09-25 06:58:21 UTC
(In reply to Michele Locati from comment #13)
> But there's no nuget package with that ID at the moment:
> https://www.nuget.org/packages?q=LibreOffice.Bindings

Yes, that package is not actually hosted on nuget.org, since it's not standalone, and instead needs a compatible build of LibreOffice to work, i.e. one that also contains some recently added native libraries.

For some reason, the dev builds of the SDK don't seem to contain the nupkg file. As Mr. Kaganski mentioned, there should be a file named <sdk>/dotnet/LibreOffice.Bindings.0.1.0.nupkg. But even so, just getting the nuget package won't work, since those aforementioned native libraries need to be present in the LO install. 

Until the next LO release, unfortunately, the path of least resistance would be to build LO locally with the --with-dotnet option, enabling the SDK with the setsdkenv_windows/linux scripts, and adding <RestoreAdditionalProjectSources>[path/to/sdk]/dotnet</RestoreAdditionalProjectSources> and <PackageReference Include="LibreOffice.Bindings" Version="0.1.0" /> to your .csproj file.

The docs on using the bindings are lacking right now, but I'll try to work on them as soon as I can. Apart from this a standalong version of the bindings is also in the works, but it might be some time before it's functional.
Comment 16 Mike Kaganski 2024-09-25 07:24:04 UTC
Marking it FIXED, because it definitely not "INVALID", and moreover, the GSOC change basically specifically targeted the problem here.