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)
Does anyone fixing this error or can say something about it?
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?
Bug is still exist in 7.6.2.1 version of SDK. I'm using .NET 7.
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?
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.
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.
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.
I the net8 error System. InvalidOperationException: "Handle is not initialized." This is normal in the netframework Faulty code m_xContext = uno.util.Bootstrap.bootstrap();
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().
*** Bug 163072 has been marked as a duplicate of this bug. ***
> 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).
(In reply to Michele Locati from comment #11) The sample's Makefile points to a nupkg in sdk/dotnet?
(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
(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
(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.
Marking it FIXED, because it definitely not "INVALID", and moreover, the GSOC change basically specifically targeted the problem here.