How can I convert a .NET exe to Win32 exe? (I don't have the code)
The purpose is to run the application in Linux using wine. I presume that .NET exe cannot be run in wine and I don't want to use mono.
depending on what version of .NET it is and what libraries it makes use of you could try running it under Mono without compiling the IL down to native code.
most Linux distributions have it available under their package management systems.
see: http://www.mono-project.com/Main_Page for more details
the alternative is to use NGen to do the compiling (http://blogs.msdn.com/clrcodegeneration/archive/2007/09/15/to-ngen-or-not-to-ngen.aspx). but i'm not sure that would work under WINE.
Depending on your framework version it might work with Wine
.Net Framework compability in Wine
This is probably a difficult solution for you, but I mention it here in the interest of completeness.
You can supposedly wrap a .net application with VMWare's Thinapp. I believe this results in a win32 executable.
https://www.vmware.com/products/thinapp
Perhaps it will run under mono?
Use the ahead-of-time compiler with static libraries. A.k.a. mkbundle on mono
Mono comes with a commandline interface to the mono JIT compiler to compile AOT (ahead of time). You can use this to create a statically linked .o that you can then run with a trivial wrapper that invokes the mono runtime embedder with the object file. If you then statically link to the mono libraries, you won't have any external dependencies to an installed .NET framework.
Of course, you will have to ship all the statically linked libraries or end up with a hughe exe but hey, it's what you asked for
mono --aot=static
static Create an ELF object file (.o) which can be statically linked into an executable when embedding the mono runtime. When this option is used, the object
file needs to be registered with the embedded runtime using the mono_aot_register_module function which takes as its argument the mono_aot_module_<ASSEM‐
BLY NAME>_info global symbol from the object file:
extern void *mono_aot_module_hello_info;
mono_aot_register_module (mono_aot_module_hello_info);
While I used this on linux, I'm not completely sure it works on windows equally well.
Update Remembered the mkbundle tool:
sehe#sehelap:~$ mkbundle --static test.exe -o hello
OS is: Linux
Note that statically linking the LGPL Mono runtime has more licensing restrictions than dynamically linking.
See http://www.mono-project.com/Licensing for details on licensing.
Sources: 1 Auto-dependencies: False
embedding: /home/sehe/test.exe
Compiling:
as -o temp.o temp.s
cc -o hello -Wall `pkg-config --cflags mono` temp.c `pkg-config --libs-only-L mono` -Wl,-Bstatic -lmono -Wl,-Bdynamic `pkg-config --libs-only-l mono | sed -e "s/\-lmono //"` temp.o
Done
sehe#sehelap:~$ ./hello
hello world
sehe#sehelap:~$ ldd hello
linux-gate.so.1 => (0xb7875000)
libdl.so.2 => /lib/libdl.so.2 (0xb785f000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7845000)
libm.so.6 => /lib/libm.so.6 (0xb781e000)
libgthread-2.0.so.0 => /usr/lib/libgthread-2.0.so.0 (0xb7819000)
librt.so.1 => /lib/librt.so.1 (0xb7810000)
libglib-2.0.so.0 => /lib/libglib-2.0.so.0 (0xb7741000)
libc.so.6 => /lib/libc.so.6 (0xb75e4000)
/lib/ld-linux.so.2 (0xb7876000)
libpcre.so.3 => /lib/libpcre.so.3 (0xb75af000)
Simply not possible. For managed code, you need some kind of VM to run in. In Linux you can use Mono or dotgnu portable.net. Maybe some hyper-advanced version of wine will once be able to run the MS .net framework?
Related
I have a project developed with .NET Core and C#, running on Docker, that has to call a few functions on a DLL developed with C++.
The problem is: when I run my project without Docker, on Windows using Visual Code, the code runs smoothly, but when I run on Docker, on a Linux container, the code throws an error when trying to execute the DLL function.
I already tried copying the .dll file to the /lib folder, changing it to the parent folder of the project and none of that worked. I started to doubt that the problem is that the file is not found and, by doing some research, I saw that it could be related to the file permissions, so I ran chmod a+wrx on the .dll file, also no success.
This is my Dockerfile configuration:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
RUN apt-get update \
&& apt-get install -y --allow-unauthenticated \
libc6-dev \
libgdiplus \
libx11-dev \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get install -y poppler-utils
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
COPY . .
RUN dotnet restore --configfile Nuget.config -nowarn:msb3202,nu1503
RUN dotnet publish -c Release -o ./out
FROM base AS final
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MdeGateway.dll"]
This is the code that tries to access the DLL function:
[DllImport("MyDll.dll")]
private static extern int dllfunction(Int32 argc, IntPtr[] argv);
public static void CallDll(string[] args)
{
IntPtr[] argv = ArrayToArgs(args);
dllfunction(args.Length, argv);
FreeMemory(args, argv);
}
The error occurs when the line 'dllfunction(args.Length, argv);' is executed.
The exact message is:
"Unable to load shared library 'MyDll.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libMyDll.dll: cannot open shared object file: No such file or directory"
Also, if someone can teach me how to set the LD_DEBUG environment variable I would appreciate it.
I have a project developed with .NET Core and C#, running on Docker, that has to call a few functions on a DLL developed with C++. The problem is: when I run my project without Docker, on Windows using Visual Code, the code runs smoothly, but when I run on Docker, on a Linux container, the code throws an error when trying to execute the DLL function.
If I am reading this right, you have a C++ application that you compiled to a .dll (on Windows). You can DllImport this .dll on Windows, but not on Linux (container). Is that right?
Are you aware that C++ code compiled into a .dll (shared library) is a Windows-specific thing? Unmanaged code is architecture and platform specific. An unmanaged .dll compiled on x64 won't run on arm64. A unmanaged .dll compiled on Windows wont run on Linux.
Linux (and Linux containers, such as in docker) can't use a .dll built from unmanaged code on Windows. Linux needs the unmanaged (C++) code to be compiled into a shared library (.so file) for DllImport (and the underlying dlopen calls) to work on Linux. Ideally on the same platform as the container it will be running in.
The mono docs cover an (one particular) implementation of DllImport and give more background on how this works on Linux:
https://www.mono-project.com/docs/advanced/pinvoke/
(But keep in mind that Mono != .NET Core. It should still give you some more background information.)
This does not give the solution to OP's problem, but helps answer his 2nd question
Also, if someone can teach me how to set the LD_DEBUG environment variable I would appreciate it.
I am facing a similar issue, and am also struggling to understand what to do with this LD_DEBUG env variable. Turns out that it controls the verbosity of the debugging info for Unix's dynamic linker.
Following the advice here, running LD_DEBUG=help cat in a linux terminal will give you all the valid options for setting LD_DEBUG.
Here's a screenshot of the output of such command:
Additional useful resources:
Linux Apps Debugging Techniques - The Dynamic Linker
Linux LS.SO man page
Quoting from LD.SO man page mentioned above:
LD_DEBUG (since glibc 2.1)
Output verbose debugging information about operation of
the dynamic linker. The content of this variable is one
of more of the following categories, separated by colons,
commas, or (if the value is quoted) spaces:
help Specifying help in the value of this variable does
not run the specified program, and displays a help
message about which categories can be specified in
this environment variable.
all Print all debugging information (except statistics
and unused; see below).
bindings
Display information about which definition each
symbol is bound to.
files Display progress for input file.
libs Display library search paths.
reloc Display relocation processing.
scopes Display scope information.
statistics
Display relocation statistics.
symbols
Display search paths for each symbol look-up.
unused Determine unused DSOs.
versions
Display version dependencies.
Since glibc 2.3.4, LD_DEBUG is ignored in secure-execution
mode, unless the file /etc/suid-debug exists (the content
of the file is irrelevant).
In trying to build NuGet3, I'm getting the following error:
~/Projects/NuGet3-dev/src/NuGet.CommandLine/project.json(22,46): error: The dependency fx/Microsoft.Build.Framework >= 14.0.0 could not be resolved.
I have no idea why it wouldn't be resolved, since according to
gacutil -l
I have it:
Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
I looked at everything I could find about this issue, but it's almost entirely Visual Studio and Windows based resolutions, and nothing seems to apply to my situation...
How to make this resolve?
(Assuming you are working on https://github.com/NuGet/NuGet.CommandLine ...)
How to resolve?
Use Windows. This project is not designed to be built on Mono. It is integrated with Windows tooling.
Under POSIX systems (thought, some true operating system):
In short, the dependency is resolved using DNX or dotnet (said M$ .Net Core), and its restore command.
The fx/ stands for framework, just drop the prefix, it should be the same. I sow these kind of notations disappear, when passing to DNX. Just try and install it using the DNX process.
since MSBuild targets and props for DNX are not available, the xbuild script from Mono won't work.
You'll have to use one of
the "deprecated" dnvm.sh script and dnx/dnu commands to restore and then build each sub project.
Note: that yet isn't anymore available at download, and the call to dnvm update-self relaces the script by a "404" ...
The "Microsoft .NET Core Shared Framework Host", "dotnet" (that I don't use)
It should mostly work, if you've got Dnx, try this command line, from the src sub-dir of the NuGet3 source code:
(for d in *; do (cd $d && dnu restore && dnu build); done)2>&1|tee build-all.log
For me, using Debian-8, there are build failures:
NuGet.CommandLine.XPlat
NuGet.Configuration, but it succeeds for the "net451" framework
NuGet.Packaging.Core
NuGet.Packaging
NuGet.Protocol.Core.v3, but it's OK #dnxcore50 (don't ask me why) ...
YANote: If code cannot be transformed anywhere but by M$, this is cannot be source code for me : I cannot not use it as a source. This is a secret code, a private code ... something to throw away, and that probably no one cares.
I've a C# project: https://github.com/Pro/dkim-exchange
It uses Travis CI: https://travis-ci.org/Pro/dkim-exchange
Travis successfully builds my project.
I wanted to set up Coverity to do automatic code quality measurements. For this I configured my .travis.yml as follows:
language: objective-c
env:
global:
- EnableNuGetPackageRestore=true
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "kC7O0CWm9h4g+tzCwhIZEGwcdiLrb1/1PijeOKGbIWGuWS7cIksAkj2tRNMgtxxcE9CFQr8W7xDv2YzflCIlqN1nGkFjbyD4CrNg6+V1j0fZjPOQ6ssdBBVPrfrvecsAUJ0/48Tqa9VTkEpZSlwOF/VS1sO2ob36FVyWjtxvG9s="
matrix:
- MONO_VERSION="3.10.0"
install:
# Fetch Mono
- wget "http://download.mono-project.com/archive/${MONO_VERSION}/macos-10-x86/MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg"
- sudo installer -pkg "MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg" -target /
script:
- xbuild travis.proj
addons:
coverity_scan:
project:
name: "Pro/dkim-exchange"
description: "Build submitted via Travis CI"
notification_email: mail#example.com
build_command_prepend: "xbuild /t:CleanAll travis.proj"
build_command: "xbuild /t:Build travis.proj"
branch_pattern: coverity_scan
If I execute the coverity build commands as indicated here (using msbuild): https://scan.coverity.com/download?tab=csharp the uploaded archive is analyzed correctly, but in combination with travis, the coverity analysis fails (see e.g. this build log: https://travis-ci.org/Pro/dkim-exchange/builds/42295611).
There's this warning:
[WARNING] No files were emitted. This may be due to a problem with your configuration
or because no files were actually compiled by your build command.
Please make sure you have configured the compilers actually used in the compilation.
I think this may be related to xbuild from Mono. Unfortunately Dr. Google didn't find anythin about Coverity+xbuild. Does Coverity support xbuild? If yes, how can I correctly setup the project?
When it comes to C#, Coverity actually only supports msbuild.
You can find some more official information about this in the following
http://www.coverity.com/library/pdf/CoverityStaticAnalysis.pdf
https://communities.coverity.com/message/6251#6251
The last link explicitly states
Our C# analysis only supports the Visual Studio C# compilers
So, no xbuild support as of now.
Update:
When you download the Coverity build tool, the doc/en/help/cov-build.txt explicitly states the following:
C# build capture is only supported on Windows.
I'm trying to interop with the ImageMagick library in Mono on a Mac. I installed the ImageMagick library with MacPorts and have verified that the file libMagickWand.dylib exists in the directory /opt/local/lib. I've also created a soft link to that file in the directory /usr/local/lib.
Here's my DllImport statement:
[DllImport("libMagickWand", EntryPoint = "MagickWandGenesis")]
static extern void WandGenesis();
Here's my App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<dllmap dll="libMagickWand" target="/opt/local/lib/libMagickWand.dylib" />
</configuration>
And, at the call to WandGenesis();, I get a DllNotFoundException, with the message 'libMagickWand'.
I've read this page and I think I'm following all the rules. Is there anything else I can try?
Update:
I ran the .exe with MONO_LOG_LEVEL=debug. Here is the pertinent information:
Mono: DllImport error loading library 'dlopen(/opt/local/lib/libMagickWand.5.dylib, 9):
no suitable image found.
Did find: /opt/local/lib/libMagickWand.5.dylib: mach-o, but wrong architecture'.
wrong architecture: I'm running Snow Leopard in 32-bit mode and always have. I installed ImageMagick with MacPorts, and I installed Mono with the Mac package from mono-project.com. What would have been compiled with a different architecture?
Update:
I think I found my problem:
MacBook-Pro:lib ken$ lipo -info libMagickWand.5.dylib
Non-fat file: libMagickWand.5.dylib is architecture: x86_64
Update:
...but I'm still having issues. I can't seem to figure out how to compile ImageMagick with i386 architecture. When I try to do so using flags, it complains about other libraries that were compiled as 64-bit.
Update:
Mono on Mac OS X is 32 bit (at least usually, you can confirm that with mono --version) and you are trying to link with 64bit binary which is not possible. You have to provide 32-bit binary (or use 64-bit Mono).
Do you have the error even when only the library's file name is in the target and the library is placed appropriately (or the DYLD_LIBRARY_PATH set)? In such case please provide the output of mono executed with MONO_LOG_LEVEL=debug.
I am having to building mono from sources, since the Ubuntu package from badgerports is outdated (does not support .Net 4.0)
This is what I have done so far (mostly following instructions here):
cloned mono git repository
switched to branch tagged 2.6 (git checkout mono-2-6)
installed minimal mono on my machine so mono and mcs are available on machine
run ./autogen.sh --prefix=/usr/local
run make
After a few modules compile correctly, I get this error:
make[4]: Entering directory `/home/oompah/work/dev/mono/mono/mini'
CC mini.lo
CC liveness.lo
liveness.c: In function ‘mono_liveness_handle_exception_clauses’:
liveness.c:137: error: ‘MonoCompile’ has no member named ‘header’
make[4]: *** [liveness.lo] Error 1
make[4]: Leaving directory `/home/oompah/work/dev/mono/mono/mini'
make[3]: *** [all] Error 2
I have looked at the offending code, and indeed a header member is being accessed ...
void
mono_liveness_handle_exception_clauses (MonoCompile *cfg)
{
MonoBasicBlock *bb;
GSList *visited = NULL;
MonoMethodHeader *header = cfg->header;
...
}
Has anyone managed to build mono-2.6 (or later) on Ubuntu?
I've used the scripts provided at integratedwebsystems successfully to compile a recent version of mono on my system and run .net 4.0 applications.
an improved version of the script can be found on firegrass' github account
Joe Shields is packaging Mono 2.10 and is patching everything to default to .NET 4.0 for Ubuntu, you might want to poke him on twitter #directhex.