I just had a look at previous questions on topic, but I've got some strange results.
First of all, I followed and used the method that Scott Hanselman proposed in a old post in his blog: http://www.hanselman.com/blog/HowToProgrammaticallyDetectIfAnAssemblyIsCompiledInDebugOrReleaseMode.aspx
Thus, Using the IsJITOptimizerDisabled I'm supposed to check if a particular DLL has been compiled in release mode or in Debug mode.
The strange thing is that I just tried it, built a simple App that check that property and notify the assembly inspected is in debug or in release mode. Checked the results and everything it's ok against two dll I already compiled in both modes.
Then I passed that simple app to a colleague that confirm that in his workstation the results are as expected, the Debug dll show "Debug", the release show "Release" (those two dlls are contained in the same zip of the simple app).
But, when he tries to check those dlls with that simple app in another server (via mstsc) for both of the dll the simple app show "Debug" (even if opening the DLL with ILDASM everything seems fine and some specific methods contained inside a "#if DEBUG" region are not present in the Relase dll).
Now, I'm going mad, is there some reason behind this issue? Am I just too old to see what's going on ? Could be the reflection somehow dependant among the environment? Is there some Service pack that solved a similar known issue ?
Cheers,
Gianluca
The DebuggableAttribute is an attribute which is not compiled into the IL code contained in the executable assembly. It is inserted by the runtime when the assembly is loaded. The creation of the attribute might be affected by environment settings.
For example, a profiler being enabled on the system might have created environment variables or Registry settings that affect the debugging flags. A thread on the MSDN forums suggest to check for environment variables named COR_* or Registry settings under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework (and possibly HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework as well).
Using Assembly.LoadFrom() is not a very good idea in this specific case. Use fuslogvw.exe to find out why your program loaded the wrong assembly. GAC, probably.
Anyhoo, LoadFile() is called for here.
Related
I wrote a program with .Net 4.0 in C#, and it works well in the two computers in which I compiled it. But when I copy the program into other's computers, the program even didn't show it's UI, and gives out a MessageBox like this:
The box says my program has cause an APPCRASH. Anyone has any idea how to fix the problem?
Could be several reasons. One of the more common ones is that you're compiling it for a .NET framework that the target machine does not have. Another could be that you're compiling for 64-bit, while target machines are 32-bit.
Some of the steps to fix this:
If you're using Visual Studio, right click on your project and go to Properties.
In Application tab check to see which Target framework is being listed. It could be .NET Framework 4.5.1.
Change it to .NET Framework 4 Client Profile and see if it runs on your target machines.
Also, under Build check to see which Platform target options you have selected and adjust accordingly. It might be helpful to select x86 rather than Any CPU.
Other thoughts/tips:
From the screenshot, it appears that you're running it on Windows 7 machines, so I doubt that .NET framework is the issue; in that case, ensure that target machines contain all the appropriate libraries that you're using. If you have some non-native libraries, make sure that you set Copy Local to true for them.
By the way... when you say you copy it, I'm assuming you're copying all the appropriate files along with the executable, right? There might be some files, such as libraries, app configuration files, etc., that you need to copy along with it.
David Khaykin mentioned the fact that you might have an unhandled exception there. Therefore, as suggested in this SO thread, you may want to implement an event handler for the AppDomain.CurrentDomain.UnhandldedException event and check the value of the e.ExceptionObject.ToString().
Here's MSDN link to help you with that (scroll to the bottom to see an example): http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception(v=vs.110).aspx
Some ways to analyze crashes:
Here's a neat article that describes how to analyze your crashes:
http://blogs.msdn.com/b/anandbms/archive/2005/04/20/410225.aspx
It uses AdPlus, which you can read more about and obtain at http://support.microsoft.com/kb/286350
Here's a more direct link to WinDbg debugging tool: http://msdn.microsoft.com/en-us/windows/hardware/hh852365 (scroll down halfway and make sure you get the Windows 7 version if that's your OS).
Those are just some of the things that I've done over the course of my C# adventuring, so hopefully one of them can help you.
I encountered this issue once (APPCRASH referencing kernelbase.dll), in my case I had an issue due to a corrupted user profile (no certain cause for it , but I experienced a couple of blue screens before) which prevented some (but not all!) of my applications to abruptly not work anymore: to verify it, try creating a new Windows user on the faulty computer, copy the application over and attempt to execute it.
I checked the event log in my target machine, and foud some useful information. The information is just next to the "APPCRASH" one, and it says like "can't find a file...". Then I checked my program and found a lib haven't been copied there by the compiler.
It seems the event log can really help.
Thank you all who cared!
Ok this question is more about understanding what the issues are as I dont think anyone will be able to tell me how to fix the problem.
I am writing a .net 4 application and I have a 3rd party dll ( hasp dongle protection ) that I want to reference.
Visual studio allows me to create the reference fine and use classes contained within the dll within my code.
The first issue occurs when the program is run and the dll is actually loaded. I then get the following error.
System.BadImageFormatException: Could not load file or assembly
'hasp_net_windows.dll' or one of its dependencies. is not a valid
Win32 application
This weblink states how to fix this error. Coud someone expalain what the issue is and why im getting it.
After following this advice I then set the main project build to x86 and I then get another error replacing the other. The new error is:
System.IO.FileLoadException: Mixed mode assembly is built against
version 'v1.1.4322' of the runtime and cannot be loaded in the 4.0
runtime without additional configuration information
This weblink states how to fix the error, but I dont have an app.config in my project and want to avoid having one if at all possible. If someone could explain what the issue is again that would be helpful?
Please let me know if you require anymore information.
The issue is the "bitness" of your application. Once chosen (32 bit or 64 bit) all DLLs within that process need to be the same. This exception tells me that one of your DLLs is the wrong "bitness".
You simply cannot have DLLs with different compilation targets within a given process, a process has "bitness" affinity.
If this is a third party unmanaged DLL then it is very likely 32-bit compiled.
Setting the build output as x86 for the root project (the one that creates the exe) should suffice as this will dictate the process that is created. Any other .NET projects can then simply be Any CPU and will fit in either the 32 or 64 bit runtimes.
Unfortunately for your second issue, the provided link is the way to solve it. There is nothing wrong with having an app.config in a project and you haven't stated why you don't want one.
The answer by Adam Houldsworth notwithstanding, I'd like to add that it is possible to do it without an app.config. However, this requires a tiny bit more work and potentially a proper understanding of COM interop. Whether it's worth the trouble is up to you of course ;).
You can set useLegacyV2RuntimeActivationPolicy programmatically by using the ICLRRuntimeInfo::BindAsLegacyV2Runtime method.
A quick rundown on how to do this is posted in this blogpost. Take note of his warning though, which might make you think twice in using this approach:
This approach works, but I would be very hesitant to use it in public
facing production code, especially for anything other than
initializing your own application. While this should work in a
library, using it has a very nasty side effect: you change the runtime
policy of the executing application in a way that is very hidden and
non-obvious.
I cannot use an app.config file because the assembly is loaded via COM from a native program.
I found the library that supports .net framework 4.0. here. In this scenario, no other solutions had worked for me.
I am working on an assembly that handles various color transformations. When I load the assembly into a new project to test, if there happens to be an bug in the assembly, Visual Studio opens the offending code from the DLL. I can step through all of the code in the assembly.
I definitely don't want the code to be so easily visible/available. I would like the code to be somewhat "locked" in the assembly.
How can I set the DLL to simply throw some sort of error instead of opening?
Edit
I'm not interested in the code being "safe" and I have no need to obfuscate. This library is being used internally and the code itself is perfectly accessible to tohers. What I don't want is for someone using the library to find themselves suddenly debugging the assembly. If there is a problem, I prefer to have an error thrown instead of the assembly code opening in Visual Studio.
This is happening because you have VS installed on the machine, and because you are deploying the PDB files - you will not get this dialogue box if VS is not installed.
Additionally:
Do not deploy code that has been built in the Debug configuration. These contain additional information that helps with debugging.
Make sure you do not deploy the PDB files with the executables. Same as above, and they are not needed for running the code.
Both these will help, but any assembly would be easily decompiled with reflector, so you may also want to investigate obfuscators to stop other programmers from easily seeing your code.
There is a list of C# obfuscators here : http://www.csharp411.com/net-obfuscators/
What you need is to obfuscate your binaries.
Basically if you want your code to be safe and you dont want your classes are exposed to others, you should definitely need to Obfuscate your code.
To obfuscate your code you can use DotFuscator, it is included with Visual Studio installation.
check my article on it.
http://www.codeproject.com/KB/dotnet/code_security.aspx
I think I know what a build is. But I am not sure. My definition of a build is another word for saying compiled application. Can someone please tell me what exactly a build is. And why do people ask for 3 types of builds. Such as Debug Build, Profile Build and a Release Build. What are the differences.
[edit]
the types of builds
Have a look at Visual Studio Debug and Release Modes
Release Mode
When an assembly is built in release mode, the compiler performs all available optimisations to ensure that the outputted executables and libraries execute as efficiently as possible. This mode should be used for completed and tested software that is to be released to end-users. The drawback of release mode is that whilst the generated code is usually faster and smaller, it is not accessible to debugging tools.
Debug Mode
Debug mode is used whilst developing software. When an assembly is compiled in debug mode, additional symbolic information is embedded and the code is not optimised. This means that the output of the compiler is generally larger, slower and less efficient. However, a debugger can be attached to the running program to allow the code to be stepped through whilst monitoring the values of internal variables.
A build means basically doing a set of tasks to make your program. The main components of a typical build is compiling and linking.
More specifically a build can contain compiling, linking, setting version numbers, copying outputs to some location, creating an installer and anything else.
When people say debug or release build or etc., they may have different settings defined for each. For example in a debug build you will create program database files for debugging.
A build does not have to include only compiled and linked targets. Usually there is at least one of those, but a "build" could also include creating plain-text or binary files, moving images, sounds, and other files into the correct places to be accessed by the file, or any other operation that needs to be performed for the application to run.
The multiple types of builds are made to target different "audiences", if you will. For instance, and end-user does not need to collect information about what functions were called or how many times and exception was raised, or any other diagnostic info (though that information is valuable to developers). Usually the final "release" build is made to be fast and small, and not load the user down with extras like that.
I'm getting System.IO.FileNotFoundException: The specified module could not be found when running C# code that calls a C++/CLI assembly which in turn calls a pure C DLL. It happens as soon as an object is instantiated that calls the pure C DLL functions.
BackingStore is pure C.
CPPDemoViewModel is C++/CLI calling BackingStore it has a reference to BackingStore.
I tried the simplest possible case - add a new C# unit test project that just tries to create an object defined in CPPDemoViewModel . I added a reference from the C# project to CPPDemoViewModel .
A C++/CLI test project works fine with just the added ref to CPPDemoViewModel so it's something about going between the languages.
I'm using Visual Studio 2008 SP1 with .Net 3.5 SP1. I'm building on Vista x64 but have been careful to make sure my Platform target is set to x86.
This feels like something stupid and obvious I'm missing but it would be even more stupid of me to waste time trying to solve it in private so I'm out here embarrassing myself!
This is a test for a project porting a huge amount of legacy C code which I'm keeping in a DLL with a ViewModel implemented in C++/CLI.
edit
After checking directories, I can confirm that the BackingStore.dll has not been copied.
I have the standard unique project folders created with a typical multi-project solution.
WPFViewModelInCPP
BackingStore
CPPViewModel
CPPViewModelTestInCS
bin
Debug
Debug
The higher-level Debug appears to be a common folder used by the C and C++/CLI projects, to my surprise.
WPFViewModelInCPP\Debug contains BackingStore.dll, CPPDemoViewModel.dll, CPPViewModelTest.dll and their associated .ilk and .pdb files
WPFViewModelInCPP\CPPViewModelTestInCS\bin\Debug contains CPPDemoViewModel and CPPViewModelTestInCS .dll and .pdb files but not BackingStore. However, manually copying BackingStore into that directory did not fix the error.
CPPDemoViewModel has the property Copy Local set which I assume is responsible for copying its DLL when if is referenced. I can't add a reference from a C# project to a pure C DLL - it just says A Reference to Backing Store could not be added.
I'm not sure if I have just one problem or two.
I can use an old-fashioned copying build step to copy the BackingStore.dll into any given C# project's directories, although I'd hoped the new .net model didn't require that.
DependencyWalker is telling me that the missing file is GPSVC.dll which has been suggested indicates security setting issues. I suspect this is a red herring.
edit2
With a manual copy of BackingStore.dll to be adjacent to the executable, the GUI now works fine. The C# Test Project still has problems which I suspect is due to the runtime environment of a test project but I can live without that for now.
Are the C and C++ DLLs in the same directory as the C# assembly that's executing?
You may have to change your project output settings so that the C# assembly and the other DLLs all end up in the same folder.
I've often used the Dependency Walker in cases like this; it's a sanity check that shows that all the dependencies can actually be found.
Once your app is running, you may also want to try out Process Monitor on the code you are running, to see which DLLs are being referenced, and where they are located.
The answer for the GUI, other than changing output settings, was the addition of a Pre-Build Step
copy $(ProjectDir)..\Debug\BackingStore.* $(TargetDir)
The answer for the Test projects was to add the missing DLL to the Deployment tab of the testrunconfig. You can either do so by directly editing the default LocalTestRun.testrunconfig (appears in Solution under Solution Items) or right-click the Solution and Add a new test run config, which will then appear under the main Test menu.
Thanks for the answers on this SO question on test configurations for leading me to the answer.
The reason why this happens is because you either are loading DLLMAIN from managed code, before the CRT has an opportunity to be initialized. You may not have any managed code, be executed DIRECTLY or INDERECTLY from an effect of DllMain notifications. (See: Expert C++/CLI: .Net for Visual C++ Programmers, chapter 11++).
Or you have no native entrypoint defined wahtsoever, yet you have linked to MSVCRT. The CLR is automatically initialized for you with /clr, this detail causes a lot of confusion and must be taken into account. A mixed mode DLL actually delay loads the CLR through the use of hot-patching all of the managed entry point vtables in your classes.
A number of class initialization issues surround this topic, loader lock and delay loading CLR are a bit trickey sometimes. Try to declare global's static and do not use #pragma managed/unmanaged, isolate your code with /clr per-file.
If you can not isolate your code from the managed code, and are having trouble, (after taking some of these steps), you can also look towards hosting the CLR yourself and perhaps going through the effort of creating a domain manager, that would ensure your fully "in-the-loop" of runtime events and bootstrapping.
This is exactally why, it has nothting todo with your search path, or initialization. Unfortunately the Fusion log viewer does not help that much (which is the usual place to look for .NET CLR assembly binding issues not dependency walker).
Linking statically has nothing todo with this either. You can NOT statically link a C++/CLI application which is mixed mode.
Place your DLLMAIN function into a file by itself.
Ensure that this file does NOT have /CLR set in the build options (file build options)
Make sure your linking with /MD or /MDd, and all your dependencies which you LINK use the exact same CRT.
Evaluate your linker's settings for /DEFAULTLIB and /INCLUDE to identify any possiable reference issues, you can declare a prototype in your code and use /INCLUDE to override default library link resolution.
Good luck, also check that book it's very good.
Make sure the target system has the correct MS Visual C runtime, and that you are not accidentally building the C dll with a debug runtime.
This is an interesting dilemma. I've never heard of a problem loading native .DLLs from C++/CLI after a call into it from C# before. I can only assume the problem is as #Daniel L suggested, and that your .DLL simply isn't in a path the assembly loader can find.
If Daniel's suggestion doesn't work out, I suggest you try statically linking the native C code to the C++/CLI program, if you can. That would certainly solve the problem, as the .DLL would then be entirely absorbed into the C++/CLI .DLL.
Had the same problem switching to 64-bit Vista. Our application was calling Win32 DLLs which was confusing the target build for the application. To resolve it we did the following:
Go to project properties;
Select Build tab;
Change 'Platform target:' option to x86;
Rebuild the application.
When I re-ran the application it worked.