We have a Windows Service app written in C# targeted for AnyCPU. It runs on a Win2003 (32bit) server. Recently it started to run out of memory.
What is involved in redeploying this service to a Win2003 (64bit) box. Do I need to recompile it and will the App get more memory if I do not recompile it?
Nothing special if the exe is set for AnyCPU- the 64-bit CLR will load by default on a 64-bit machine. You just have to make sure you're REALLY AnyCPU ready (no unsafe OR safe 32-bit pointer math assumptions, etc). If you're running all managed code with no PInvokes, you should be in good shape.
Related
I have an application that we're trying to migrate to 64bit from 32bit. It's .NET, compiled using the x64 flags. However, we have a large number of DLLs written in FORTRAN 90 compiled for 32bit. The functions in the FORTRAN DLLs are fairly simple: you put data in, you pull data out; no state of any sort. We also don't spend a lot of time there, a total of maybe 3%, but the calculation logic it performs is invaluable.
Can I somehow call the 32bit DLLs from 64bit code? MSDN suggests that I can't, period. I've done some simple hacking and verified this. Everything throws an invalid entry point exception. The only possible solution i've found so far is to create COM+ wrappers for all of the 32bit DLL functions and invoke COM from the 64bit process. This seems like quite a headache. We can also run the process in WoW emulation, but then the memory ceiling wouldn't be increased, capping at around 1.6gb.
Is there any other way to call the 32bit DLLs from a 64bit CLR process?
You'll need to have the 32-bit dll loaded into a separate 32-bit process, and have your 64 bit process communicate with it via interprocess communication. I don't think there is any way a 32-bit dll can be loaded into a 64 bit process otherwise.
There is a pretty good article here:
Accessing 32-bit DLLs from 64-bit code
You need to write your executable processes as 32-bit processes (versus Any CPU or x64) so that they'll be loaded with WoW32 for Vista. This will load them in the 32-bit emulation mode and you won't have the entry point problem. You can leave you libraries in AnyCPU mode, but your executables have to be compiled as x86.
John's answer is correct if you don't want to recompile your existing dlls; however that might be an option for you as well.
Our team is currently migrating our x86 FORTRAN code to x64 to increase the memory ceiling.
I am designing a client application that will list several applications that I offer. A user will pick the application, and press run, then the application will be downloaded and will be loaded into the client application's domain using Assembly.Load. Here's the snippet of where it gets loaded:
var vAsm = Assembly.Load(client.GetBase());
var vEP = vAsm.EntryPoint;
var vSC = vAsm.GetType(vEP.DeclaringType.FullName).GetMethod("SetClient");
var vInst = vAsm.CreateInstance(vEP.Name);
vSC.Invoke(vInst, new object[] { client, license });
vEP.Invoke(vInst, null);
Problem: Two of the current applications are 32bit. However one of my applications is 64bit.
Question: If I build the client application in AnyCPU, will it be able to load both the 32bit applications AND the 64bit application? Or is there maybe a setting that launches it in 64bit if the machine supports it? This would be ideal, as I would just detect if they are 32bit/64bit and warn them that the one application is not supported on their machine if that's the case.
I will be testing this myself, but maybe somebody could give me some sort of advice to handle this.
Thanks!
To answer your first question, if you compile the application as AnyCPU you let Windows decide which CLR to pick. In my experience, it usually works out to Windows picking the x64 CLR on x64 operating systems and the x86 CLR on x86 operating systems but I'm not certain if that's always a guarantee. AnyCPU does not mean that it gets to run in both. You will only be able to load the version of the application which corresponds to the architecture of the CLR which loaded your client application.
I've had to deal with this sort of thing in some of the applications that I work with at the place where I'm working. I've run into some frustrating bugs when I tried interoperating with applications compiled for a specific architecture and applications compiled for AnyCPU. To make things easier and more predictable, I just ended up compiling the "AnyCPU" applications which had to interact with the "non AnyCPU" applications for each architecture for which they had to interact. There may be some people who have a more sophisticated setup but it wasn't worth the headache for me.
So, the answer to the second question is more advice. I'd just compile the client application for a specific architecture so that you know for sure which architecture that you're dealing with and then add appropriate code to detect the architecture. In fact, I think that you could use some compiler directives to store some sort of indicator as to which architecture that you're running under or even put a "detection" branch specific to each architecture in the compiler directive and that would help you do the warning that you're thinking of doing.
The alternative is to keep the client application as AnyCPU and detect which architecture the application is currently running under (if memory serves, it's IntPtr.Size == 8 for x64 applications but there may be more reliable methods; not sure...) and then only launch the appropriate applications. But still, you have to be mindful of the fact that, even with AnyCPU, you can only load applications of the specific architecture of the CLR which is running your AnyCPU client application.
Does that make sense?
You should build all your binaries in AnyCPU. That way, on a 64-bit OS, they'll run as 64-bit and on a 32-bit OS, they'll run as 32-bit. If you compile to x64, it won't run on a 32-bit OS at all. If you compile to x86, you'll always run as 32-bit, even on a 64-bit OS. The final rule is that you can't mix & match x86 and x64 bins in the same process. The mismatching ones will fail to load.
I have compiled a c natives 32bit DLL with Dev-C++, create the reference on my asp.net project, write a dllImport directives and use my new DLL. When launch my DEBUG session all work very well but when deploy my project on Web Server the runtime not load my DLL.
My IIS 7.0 w3wp.exe runs as a 64 bit process (to check if your process running as a 32 bit process under WOW64, open the task manager's Process tab and see if the process name contains "*32").
I believe that a 64 bit process can only load 64 bit native DLLs (and managed DLLs built for "Any CPU" or "X64"). Perhaps your debug session is a 32 bit session? If this is the cause, take a look at Using a 32bit or 64bit dll in C# DllImport .
For those of you who still cannot find a proper way to use a 32-bit DLL under a 64-bit IIS Application Pool, either by tweaking the registry, or by trying how to deal with the "COM+ Components Services", I have found a perfectly working solution : "Encapsulating" the 32-bit component into a new COM object as described on this page did the job perfectly, and I think that a lot of you will be interested to solve the problem this way ;)
http://www.chestysoft.com/component-services.asp
In my case, that allowed me to use the "XStandard.Zip" free Component from XStandard, which is sadly only available as a 32-bit ASP component, and that have an "InProcServer32" Key in the registry apparently preventing it to work by tweaking the registry, as described here : https://techtalk.gfi.com/32bit-object-64bit-environment/
In this post, a lot of comments reported that "InProcServer32-IDs are not reflected because Microsoft assumes that these are only InProc-Calls and not Out-Of-Proc-Calls".
And that was my case too, leading me to the situation where the registry tweaking solution described in the previous post was not working in my case, as other users.
Hoping having saved some days... or nights !
I have created a WPF Windows Application project based on the existing standards in the solution. The project properties had Platform Target as Any CPU and says Prefer 32-bit. Mine is a 64-bit machine and the application wasn't launching, it took me while to figure out and turned off Prefer 32-bit to launch it.
My question is what is happening when I say Prefer 32-bit? I expect it to launch it as a 32 bit application on a 64-bit machine. But in my case it does not run, it simply terminates. Why?
Edit:
The problem was when I say Prefer 32-bit or x86 it builds the application in 32-bit mode. Any CPU makes it a 64-bit build. The application launches only in 64-bit mode and when launched with 32-bit mode it terminates without any exception.
After trial and error found out that problem is with the length of the AssemblyName. It was 56 character long after I reduced it to say 36 character it worked fine. Could not get information on whats the permissible limit for 32-bit assembly name and 64-bit assembly name. But 64 bit allows bigger names which has caused the confusion.
Does a application in .NET need to be built in 64 bit to take full advantage of a machine with a 64 bit OS on it, or will it take advantage of it just as a 32 bit build. Basically, we have an issue with an out of memory exception and it was suggested to run the console app on a 64 bit box which "may" solve the issue. The question is can we just spin up a 64 box and throw the current app on it or do I need to rebuild the app in a 64 bit way.
If your app is configured to build for the "Any CPU" platform, then it'll run appropriately on either.
Just make sure it doesn't use any 32/64 bit specific stuff, or you'll run into problems.
MSDN docs here.
For some discussion on drawbacks, see here
If it's built for any platform (the default), it will run in 64 bit on 64bit operating systems.
That being said, there are still potential issues to watch for. If you interface with native code (via p/invoke, C++/CLI, or COM), then you will need to port that code to 64 bit. If the application is 100% managed, it just works.
"Any CPU" is your friend.
As an aside:
We had a particularly large Trie structure that exceeded the 2GB memory space of 32bit Windows. Because most of the structure comprised of object references, we found that the memory requirements of the app nearly doubled when moving to 64bit, requiring around 4gb. This is because the memory to store a reference is 64bits wide instead of 32.