System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

All about Sub-20 Multi Interface USB Adapter USB to I2C, SPI, GPIO, RS232, RS485, Ir, LCD

Moderator: serg

Post Reply
jrager
Posts: 6
Joined: Fri Oct 13, 2023 12:38 pm

System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by jrager »

Hello,

I'm having a problem incorporating the SUB-20 library into a C# program. Program runs fine in debug. Build and publish commands run without error, but running the published exe results in a System.BadImageFormatException being thrown on call to sub20dnc_v4.dll. I'm using .Net version 7.0.203 and version 1.4.28.0 of the SUB-20 library.

I've tried using both the x86 and x64 versions of the library.

When using the x86 version I set PlatformTarget in .csproj to x86 and publish using: dotnet publish -p:PublishDir=publish -c Release -r win-x86 --sc true -p:PublishSingleFile=True

When using the x64 version I set PlatformTarget in .csproj to x64 and publish using: dotnet publish -p:PublishDir=publish -c Release -r win-x64 --sc true -p:PublishSingleFile=True

Both attempts result in the same System.BadImageFormatException being thrown when running my exe.

Here is a copy of my code for the x86 version - very simple - just gets and displays serial number of the connected device(s):

using Xdimax;

Sub20Enum sub20Enum = new();
Sub20 sub20 = new();

int deviceRef = sub20Enum.GetNext(0);
while (deviceRef > 0)
{
if (sub20.Open(deviceRef))
{
var sn = sub20.GetSerialNumber();
Console.WriteLine($"deviceRef: {deviceRef} sn: {sn}");
sub20.Close();
} else
{
var errMessage = sub20.GetStrError(sub20.GetLastError());
Console.WriteLine($"Open failed: {errMessage}");
}
deviceRef = sub20Enum.GetNext(deviceRef);
}

Here's a copy for the x64 version (only change is deviceRef defined as a ulong):

using Xdimax;

Sub20Enum sub20Enum = new();
Sub20 sub20 = new();

ulong deviceRef = sub20Enum.GetNext(0);
while (deviceRef > 0)
{
if (sub20.Open(deviceRef))
{
var sn = sub20.GetSerialNumber();
Console.WriteLine($"deviceRef: {deviceRef} sn: {sn}");
sub20.Close();
} else
{
var errMessage = sub20.GetStrError(sub20.GetLastError());
Console.WriteLine($"Open failed: {errMessage}");
}
deviceRef = sub20Enum.GetNext(deviceRef);
}

I'd prefer to be using the x64 version in my app.

Since the program runs fine when debugging, I'm assuming there's an issue with publishing to the exe. Could you tell me why this would be?

Thank you,
John

serg
Posts: 143
Joined: Mon Aug 31, 2009 9:17 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by serg »

Hello John,

I couldn't build the C# project with your snippet due to some syntax errors. Could you please try to build the C:\Program Files\SUB-20\sample\.NET\c#\enum solution on your environment and see if you can run the resulting executable ? Please do the following

- Open the solution file in your MSVS20??, replace the reference to sub20dnc.dll with a reference to C:\Program Files\SUB-20\bin\x64\sub20dnc_v4.dll
- Change the "Platform target" to x64 in the "build" tab of the project properties page
- Build the project, try to launch the resulting executable.

I have just verified these steps on my MSVC2017 with .NET target framework 4.6.1. I don't think that targeting .NET 7.x.x would make any difference, but who knows...
What MSVS version do you use to build the project?

jrager
Posts: 6
Joined: Fri Oct 13, 2023 12:38 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by jrager »

Thank you for your reply serg.

I'm using MSVS 22 version 17.5.3 for this project.

I tried your suggestion, and the build exe runs fine.

I also built my sample project, and that build exe runs fine.

I believe where the problem lies is in attempting to publish as a single-file executable. When I try that with either project and run the published exe, I get the System.BadImageFormatException thrown indicating a problem with sub20dnc_v4.dll. If I don't publish as a single file, it runs fine. Could you shed any light on why this might be? If no solution I guess I could package up all the generated files, but I'd much rather publish as a single exe - much cleaner and less chance of an install getting corrupted.

Side note: the reason you were seeing the syntax errors in my sample is due to the .NET 7 I'm using. Since .NET 5, MS introduced top-level statements to C# (file-level namespaces, no need to put "main" logic inside a class, etc.)

serg
Posts: 143
Joined: Mon Aug 31, 2009 9:17 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by serg »

Hi John,

Today I tried the Build->Publish option of the MSVC2022 and it seems works properly i.e. the target package contains the correct version(architecture) of the sub20dnc_v4.dll i.e. x64. After installing the package on a fresh Win10x64 VM - I have got the "File not found" exception

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'sub20dnc_v4.dll' or one of its dependencies. The specified module could not be found.
at enum.Program.Main(String[] args)

This is because
1) The package doesn't contain the main SUB-20 interface library - sub20.dll which can be taken from c:\windows\system32 folder on your development machine
2) The sub20dnc_v4.dll is built under MSVC2010, it seems Win10 doesn't have a runtime support for it preinstalled, thus I had to install the MSVC2010 redistributable package https://www.microsoft.com/en-us/downloa ... x?id=26999

After that the executable launched without issues

Can you please verify that the exception you get is the "Bad Image format" and not the "The specified module could not be found"?
Also, please compare the sub20dnc_v4.dll (size) with the one found under C:\Program Files\SUB-20\bin\x64. They should be the same which would mean that the MSVC builder picked up the correct library

jrager
Posts: 6
Joined: Fri Oct 13, 2023 12:38 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by jrager »

Hi serg, sorry for the delayed reply.

Yes, I'm definitely receiving the BadImageFormat exception.

When you did your publish, did you specify the single-file option? Because if I publish without specifying single-file, my published project runs fine. It's only when I specify single-file = true that I receive the BadImageFormat exception reported on the sub20dnc_v4.dll.

If there's no way around it, I can go with the regular publish if I have to - but would rather publish as a single file if possible since it would make for a cleaner install.

Note that I'm also specifying self-contained during publish so as to not require that a user separately install .NET.

Thanks so much for your assistance with this - hopefully we can find a solution.

John

serg
Posts: 143
Joined: Mon Aug 31, 2009 9:17 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by serg »

Hi John,

I am new to the dotnet/msbuild. I am desperately trying to resolve the following error I am getting while running the "dotnet publish ..." command

C:\Users\serg\Desktop\SUB-20\sample\.NET\c#\enum>dotnet publish /p:Configuration=Release /p:Platform="Any CPU" --sc true -p:PublishSingleFile=True
MSBuild version 17.7.3+4fca21998 for .NET
Determining projects to restore...
Nothing to do. None of the projects specified contain packages to restore.
enum -> C:\Users\serg\Desktop\SUB-20\sample\.NET\c#\enum\bin\Release\enum.exe
C:\Program Files\dotnet\sdk\7.0.403\Microsoft.Common.CurrentVersion.targets(6027,5): error MSB4062: The "Microsoft.Buil
d.Tasks.GenerateBootstrapper" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. Confirm that the <UsingTask> declaration is correct, that the assemb
ly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Fr
amework.ITask. [C:\Users\serg\Desktop\SUB-20\sample\.NET\c#\enum\enum.csproj]

I have tried msbuild as well. The msbuild doesn't fail with such an error, however I am not able to build a "single file" on the output, it always contains setup.exe, enum.exe and bunch of other stuff

I will keep trying to find a solution and let you know once I have one

jrager
Posts: 6
Joined: Fri Oct 13, 2023 12:38 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by jrager »

Hi serg,

I haven't run into that publish issue. On my end, the publish completes and generates a single exe and a pdb into my publish folder. It's only when I attempt to run the exe that it fails with the BadImageFormatException.

FWIW, here's the publish command I've been using:

Code: Select all

dotnet publish -p:PublishDir=publish -c Release -r win-x64 --sc true -p:PublishSingleFile=True
I also tried switches similar to yours:

Code: Select all

dotnet publish -p:PublishDir=publish -c Release --sc true -p:PublishSingleFile=True -p:Platform="Any CPU"
In both cases, the publish completes but running the resulting exe produces the same exception.

I haven't had much experience with publishing to a single file, but was surprised to see that it even incorporates the sub20dnc_v4.dll itself into the exe. I would've expected that it would have just copied it to the publish folder and referenced it. That raises a question in my mind. Because sub20dnc_v4.dll depends on sub20.dll, but sub20.dll isn't incorporated inside sub20dnc_v4.dll, I wonder if there's something going on where the publish command isn't resolving this dependency and the sub20dnc_v4.dll that it's incorporating is left in some unusable state?

It's just a thought. I'll have to do a little research to see if there's been any reported issue with publishing to a single file when a DLL that is in the project references depends on another DLL that isn't in the project references.

Thank you for continuing to try to track this issue down!
John

jrager
Posts: 6
Joined: Fri Oct 13, 2023 12:38 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by jrager »

Hi serg,

I believe I found the solution! It does appear to have something to do with the publish command embedding the DLL into the exe by default. By specifying CopyToPublishDirectory and ExcludeFromSingleFile in csprog, the DLL is excluded from the exe and instead copied to the output folder:

Code: Select all

  <ItemGroup>
    <Reference Include="sub20dnc_v4">
      <HintPath>C:\Program Files\SUB-20\bin\x64\sub20dnc_v4.dll</HintPath>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
    </Reference>
  </ItemGroup>
Then the generated exe runs fine. The publish command must be corrupting the DLL in some way when it attempts to embed it.

I'm good with just having to include the DLL as an additional file with the install - much better than having to include all of the separate .NET support files, etc.

Thank you again for all the time you put into trying to diagnose this - hopefully this will help someone else in the future.

Best,
John

serg
Posts: 143
Joined: Mon Aug 31, 2009 9:17 pm

Re: System.BadImageFormatException thrown by C# program using sub20dnc_v4.dll

Post by serg »

Hi John,

No problems, I am glad that you found the solution and thank you for sharing your findings. This means that I can leave this invincible problem now ;-). I was in the process of analyzing the MSBuild verbose output, hoping to figure out the reason of why it cannot produce a single self-contained output file on my setup... and I didn't succeed in this so far.

Post Reply