What might cause MSBuild to behave differently from machine-to-machine? - c#

I have a C# program (not ASP.NET or even web-related) with platform AnyCPU targeting .NET v3.5 that references a 32-bit third-party .dll. Unfortunately, I also have several "work of art" build machines in our CI pipeline that build this program. I'm trying to add another one but I can't figure out what allows it to build.
Whenever I try to build on this new machine, I get
LC : error LC0000: 'Could not load file or assembly 'ASSEMBLY' or one
of its dependencies. An attempt was made to load a program with an
incorrect format.'
So far my only lead is that someone's installed several unneeded programs (visual studio 2010, several C++ runtimes, Windows SDK, etc) but those shouldn't break my build and I don't want to uninstall things willy nilly.
Here is the command which works on my old build machine and fails on my new one:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe /property:Configuration=release;Platform=AnyCPU;TargetFrameworkVersion=v3.5 Utilities\UtilityGUI\UtilityGUI.csproj
If I change the Platform property to x86 it works on both machines. Changing it to x64 breaks it on both machines.
What could be causing this? I checked msbuild.exe.config on the machines and compared the registry under SOFTWARE/Microsoft/VisualStudio as well as SOFTWARE/Microsoft/MSBuild. I don't want to change code as it works on my other machines and branches that haven't had a merge yet couldn't build on this machine.

The problem is with your 32-bit reference. You can't load a 32-bit assembly into a 64-bit process. Is there a reason why you can't target x86 exclusively?
As for why it's building on one machine and not the other, it may be that the AnyCPU profile on one machine is set to prefer 32-bit, or it may be that the machine that's successfully building is actually a 32-bit machine and is targeting x86 out of necessity. Either way, you won't be able to produce x64 builds when referencing a 32-bit dll.

Related

32Bit DLL not building properly

We have a c# executable that loads a 32bit dll written in C++ which dynamically loads another 32bit dll (the first dll is a wrapper).
When this is built on a 32bit machine (with VS toolset v100) it all works correctly.
When it is built on a 64bit machine (with VS toolset v110) it runs on some machines, but on others it gets a FileNotFoundException on the wrapper dll. It works on some 64bit machines, fails on some and fails on at least one 32bit machine.
The failure happens in Assembly.LoadFrom, where the location comes from Assembly.GetExecutingAssembly().Location. The dll is in the same dir as the exe, which was build as x86.
If build on a 64bit machine to get a failing version, then I drop in a version of the wrapper dll built on a 32bit machine, it works properly (so it's not really a file not found problem, but rather a 'correct' file not found one).
Any ideas why this is failing? Is it the build machine, or the toolset? Or something else? Is there something I can set in the build to get it working properly (I'd like to continue building on a 64bit box)?
Do you have all dependency dlls installed on the client machines? Like VC Runtime, other libraries you depend on?

BadImageFormatException on SQLite load on certain computer

I've created a very simple console app in .NET 4.0 that will run as a scheduled task. It looks for local files that are unmodified for a certain amount of time and then parses the file, inserts a record into a MySQL database, and copies the file to the network. I'm using a local SQLite database to track which files have already been processed, but unfortunately I'm running into a problem on one system at the first SQLite operation:
System.BadImageFormatException: Could not load file or assembly 'System.Data.SQLite.dll' or one of its dependencies. is not a valid Win32 application. (Exception from HRESULT: 0x800700C1) File name: 'System.Data.SQLite.dll'
at FileDatabase.CreateDatabaseAndTable()
at Program.Main(String[] args)
This exception is thrown on one system (Windows 7 x64 Home Premium with .NET 4.0 full), but is not thrown on two other systems (dev system + one other, both Windows 7 x64 Professional with .NET 4.0 full).
From browsing other questions, I see that this can happen when the program is run in 64-bit mode since the SQLite DLL is the 32-bit version. The first thing I checked is that the active platform is x86 in the Visual Studio Configuration Manager. I also used IL DASM to verify that the output exe is 32-bit (.corflags 0x00000003 // ILONLY 32BITREQUIRED). I would prefer to keep the 32-bit SQLite DLL and target platform as x86 so that I do not have to make different versions of the application for 32- and 64-bit computers.
I've also read that this exception can occur because of a corrupted DLL file, but since it works on some computers, I think this is not the case.
Other things I've tried on the problem system that didn't help:
Searching the GAC and Windows directory for errant SQLite DLLs, but found none.
Turning off AVG anti-virus.
Running the exe directly instead of the published ClickOnce application.
Uninstalling and reinstalling the ClickOnce application.
Any suggestions would be appreciated - thanks!
Installing the full setup package from system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki seems to have solved the problem - it must have been some dependency that was not present (possibly in Windows 7 Professional but not Home?). While this solution isn't perfect for a big deployment, I really just needed it on this one computer. Thanks for RoadBump for getting me on the right path.

C# application with access database won't work on 64 bit windows 7

I made C# application for my friend which has connection to access database (mdb file). I have developed application on my computer with win7 x86 installed. My friend had XP and it worked perfectly, but now he installed win7 x64 and application doesn't work. In fact, application starts and behave regular, but cannot connect to database... Database too can be opened with access, but my application cannot connect to it.
What can be a problem? How to make my application works on both operating systems?
regards,
Vajda
Ask your friend to download and install the following file:
Microsoft Access Database Engine 2010 Redistributable
and make sure he picks the 64-bit version there (AccessDatabaseEngine_x64.exe).
By default there is no 64-bit ODBC/OLEDB driver for Access installed, but the 2010 version should work for 2007 databases as well.
You could probably also configure your program to be built for the x86 target. That would run the program as a 32-bit program, even on 64-bit OS.
Most likely, the .Net CLR is trying to fire the app up in 64bit mode by default on his new win7 box and this might be causing some issues with the referenced assemblies.
The first thing I would try is to change the Platform target of the application (go to Project properties in Visual Studio for the application) to x86 (from Any CPU) to force the application to run in 32bit mode.
If this works, you will have narrowed down your problem.
Then, after building the project, look in the bin folder to see which assemblies are being copied to the output folder. If you see any System.Data... or any other .Net assemblies that are already contained in the GAC, you'll want to delete these and then try to fire it up. This will force the application to use GAC assemblies written for 64bit use.

On some computers application can't load sqlite dll file

I wrote an application that uses sqlite and it works great on most of the systems. It is written in C#, and the only non-framework assembly is sqlite, which is included by System.Data.SQLite.dll .
I deploy it the same way on all of the machines (copy pasting the exe file, the database file and the System.Data.SQLite file). It works great for all my PC's and most of the PC's I've tried.
But then I've got reports that for some people it throws the following exception:
Could not load file or assembly
'System.Data.SQLite, Version=1.0.65.0,
Culture=neutral,
PublicKeyToken=db937bc2d44ff139' or
one of its dependencies. An attempt
was made to load a program with an
incorrect format.
Now I've made sure the dll file is in the same folder than the application exe file. It's the same dll, with the same version as stated in the exception message above.
I was really confused by this, so I created a fresh virtual machine, installed windows 7 professional on it, and just copy pasted the files, and the thing worked. So if it works on a fresh windows, I can't imagine what the other PC's could be missing...
Note: Two of those machines where the project throws the exception are also running windows 7 proffesional.
I would really appreciate any help on this, because I'm fresh out of ideas...
Here's a possibility: Is the difference between the working and not-working machines 32-bit vs. 64-bit? Are you building for "Any CPU", when you should be building for just the bitness of your external DLL?
It is possible that the machines that throw the exception are running a 64-bit version of Windows and that your program is using the AnyCPU configuration. The System.Data.SQLite DLL is a two-faced beast: a managed part and a native-part. It could be that the native-part is responsible for the exception.
See this question for more info.
Have you checked whether the target system is 64-bit or 32-bit?
It might be that one of your dependencies requires a 32-bit version of Windows. To solve the issue you can specify a platform target in the properties of your C# project: Choose x86 instead of Any CPU.

Possible 64-bit operating system issues in C# development

I'm updating my operating system to Windows 7 x64, I only have experience with running 32-bit operating systems. Does anyone have any bad/good experiences with a 64 bit environment?
For reference, the tools I use are:
Visual Studio 2008
Tortoise SVN
TestDriven.Net
Oracle 10g XE
PL/SQL Developer
Dundas Chart
Analysis Services from MS SQL Server 2008
Running on a 64-bit operating system has a number of side effects that will be noticeable to some extent. The most common issues:
Edit and Continue in Visual Studio won't work. You can fix this by forcing your .NET app to run in 32-bit mode. Project + Properties, Build tab, Platform Target = x86. Resolved in VS2013.
If you use any ActiveX controls or COM components in your .NET app you may find your program no longer works since your machine doesn't have a corresponding 64-bit version of the COM server. You'll get error 0x80040154, REGDB_E_CLASSNOTREG, "Class not registered". Same fix as above.
The 64-bit debugger doesn't support mixed-mode debugging, you'll have to commit to either Managed only or Native only debugging. Same fix as above, as long as you don't have 64-bit specific issues. Resolved in VS2010.
Poorly written P/Invoke declarations that declare an uint or int where an IntPtr is required will stop working in 64-bit mode. You'll generally get an AccessViolation exception or a failure return code. Or a PInvokeStackImbalance MDA warning. You should not have any trouble locating the mistake, just fix the declaration.
Several legacy end-of-life Microsoft libraries are not available in a 64-bit version. That's most commonly a problem with Microsoft Access databases. Same fix as above.
You must use the correct version of Regasm.exe to register [ComVisible] assemblies. Select the one from either Framework or Framework64, depending on whether the client program is going to run in 64-bit or 32-bit mode. Or both if you want the server to be available in either.
A few COM type libraries contain bit-ness dependent arguments in their method declarations. ADO 2.8 is a notable one. Be sure to use the correct bitness of Tlbimp.exe to generate the correct COM interop assembly, Visual Studio won't do this right. Same approach as Regasm.exe
A 32-bit program has a different view of the registry from a 64-bit program. Specifically the HKCR and HKLM\Software hives are virtualized. In Regedit.exe, the 32-bit visible keys are seen under the HKLM\Software\Wow6432Node key. This can cause many subtle problems with programs that use the registry. The .NET 4 RegistryKey.OpenBaseKey() allows specifying the view you want.
Again for COM, you'll have the use the correct bitness of Regsvr32.exe to register an unmanaged COM server (not .NET servers, they use Regasm.exe). Use the one in c:\windows\system32 for 64-bit servers, c:\windows\syswow64 for 32-bit servers.
Folders in the file system are virtualized, specifically c:\windows\system32 and c:\program files. A 32-bit program will see c:\windows\syswow64 and c:\program files (x86).
Installers need to take all the above issues in consideration.
I wouldn't worry too much, if each program has an x64 download link, then use that. If not then your code will run through WOW64 emulation. And it will seem to you like it is running like normal.
Please see this related question I answered about 5 minutes ago.
WOW64 refers to windows32 on windows64
and it is a transparent emulation
laywer that allows x86 programs to run
on x64 operating systems. WOW64 will
automatically be used if you run an
x86 Windows program on an x64 Windows
operating system.
I am running Windows 7 Ultimate x64.
Visual Studio 2008 works fine.
I am using Subversion, but not Tortoise. AnkhSVN works fine.
The others I have no experience with.
Majority of software I use has no issues with x64, it's been a few years since the XP x64 troubles, and people have caught up with x64 it seems.
The primary issue with development in x64 however, is when running in x64 mode in Visual Studio, you can not edit code while debugging.
You must use x86 as the target platform in order to do so.
This is one of the reasons one of the beta's for Visual Studio 2010 defaulted target platform to x32 instead of Any Platform...

Categories

Resources