MainlyI ask this because I don't want to distribute both versions, and if I need to instal a 64bit .NET on an x64 PC and a 32bit .NET on a 32 bit PC then I would need to make this check in my loader application to download the correct version for the correct PC.
If you target AnyCPU for your compilation, the app will run as 64bit on a 64bit OS, and 32bit on a 32bit OS. If you target x86, the app will run as 32bit regardless of the OS. If you target x64, the app will only run on a 64bit OS.
If you have to install the runtime from the Internet, then use the web installer. It will take care of downloading and installing the correct version on the client. This way you can target AnyCPU (or x86) and be certain that the app will run regardless of the OS.
The .NET bootstrapper automatically installs both the 32-bit and the 64-bit versions of the .NET framework on a machine with a 64-bit operating system. Nothing you have to do to tell it to do so. Avoid distributing the .NET framework yourself, you'll have a hard time keeping up with the security updates. Just tick the option in the Setup project's Prerequisites to get the bootstrapper, that will download the latest and greatest during install on the target machine, if necessary. The option is automatically ticked when you create an installer for a managed program.
The Platform Target setting in the Project + Properties, Build tab for your EXE project is relevant. It defaults to x86 in a project that was created from scratch in VS2010. There is no great reason to change it to AnyCPU for the Release build unless you need the extra virtual memory space that a 64-bit process can provide. If you do change it then do make sure to test it thoroughly. I know you've been tinkering with unmanaged COM servers, x86 is probably a hard requirement.
Recognizing the limitations imposed by this shift, and its impact on our developers, we have been working hard on features to pave the way for designing legacy WinForms 32-bit .NET Framework applications in the latest Visual Studio environment. While these initial efforts will not comprehensively solve the entire problem space, our aim is to unblock customers and make the transition to a 64-bit Visual Studio 2022 smoother.
These additions signify our commitment to actively engage with the community, understand the intricacies of their projects, and steadily build features that pave the way for the best possible Visual Studio experience. We hope this approach will make it easier for developers to eventually migrate to .NET to gain all the benefits of a more modern platform without a complete rewrite of the user interface.
In contrast to the in-process designer which loads all assemblies related to third-party controls into the Visual Studio process, the out-of-process designer needs to be pickier; it loads design-time assemblies either into a dedicated server process or into the client Visual Studio process. This distinction in assembly loading is necessary because of the client-server architecture of the out-of-process designer and as a result, third-party control vendors need to use the new designer SDK for providing controls for out-of-process designer. Note that creating different design time assemblies for client and server processes is not necessary to support simple scenarios but it is required for more advanced scenarios. Learn more about it here. As a result, the out-of-process designer for .NET Framework projects will not be able to handle all third-party controls designed for an in-process design environment. If it encounters such a control, there is a possibility that this will simply omit code related to controls the designer cannot render. Hence, we recommend that you create a backup of your project beforehand.
The first question developer ask me when I'm pushing 64-bit is "Can I still run Visual Studio the same? Can I make apps that run everywhere?" Yes, totally. I run VS2008 all day on x64 machines writing
ASP.NET apps, WPF apps, and Console apps and don't give it a thought. When I'm developing I usually don't sweat any of this. Visual Studio 2008 installs and runs just fine.
If you care about details, when you install .NET on a 64-bit machine the package is bigger because you're getting BOTH 32-bit and 64-bit versions of stuff. Some of the things that are 64-bit specific are:
Notice that a bunch of processes have *32 by their names, including devenv.exe? Those are all 32-bit processes. However, my ConsoleApplication1.exe doesn't have that. It's a 64-bit process and it can access a ridiculous amount of memory (if you've got it...like 16TB, although I suspect the GC would be freaking out at that point.)
That 64-bit process is also having its code JIT compiled to use not the x86 instruction set we're used to, but the AMD64 instruction set. This is important to note: It doesn't matter if you have an AMD or an Intel processor, if you're 64-bit you are using the AMD64 instruction set. The short story is - Intel lost. For us, it doesn't really matter.
Everyone once in a while you'll need to call from managed code into unmanaged and you'll need to give some thought to 64-bit vs. 32-bit. Unmanaged code cares DEEPLY about bitness, it exists in a processor specific world.
In 64-bit Microsoft Windows, this assumption of parity in data type sizes is invalid. Making all data types 64 bits in length would waste space, because most applications do not need the increased size. However, applications do need pointers to 64-bit data, and they need the ability to have 64-bit data types in selected cases. These considerations led the Windows team to select an abstract data model called LLP64 (or P64). In the LLP64 data model, only pointers expand to 64 bits; all other basic data types (integer and long) remain 32 bits in length.
The .NET CLR for 64-bit platforms uses the same LLP64 abstract data model. In .NET there is an integral data type, not widely known, that is specifically designated to hold 'pointer' information: IntPtr whose size is dependent on the platform (e.g., 32-bit or 64-bit) it is running on. Consider the following code snippet:
If you checked the property System.IntPtr.Size while running as x86, it'll be 4. It'll be 8 while under x64. To be clear, if you are running x86 even on an x64 machine, System.IntPtr.Size will be 4. This isn't a way to tell the bitness of your OS, just the bitness of your running CLR process.
See that lat number? Total crap. I've used an int as a pointer to lpMaximumApplicationAddress rather than an IntPtr. Remember that IntPtr is smart enough to get bigger and point to the right stuff. When I change it from int to IntPtr:
You'll also want to think about the assemblies that your application loads. It's possible that when purchasing a vendor's product in binary form or bringing an Open Source project into your project in binary form, that you might consume an x86 compiled .NET assembly. That'll work fine on x86, but break on x64 when your AnyCPU compiled EXE runs as x64 and tries to load an x86 assembly. You'll get a BadImageFormatException as I did in this post.
Regardless of which of these things your application is doing it is going to be important to do your homework and investigate what your code is doing and what dependencies you have. Once you do this homework you will have to look at your choices to do any or all of the following:
There may be cases where you make the decision either not to migrate the managed code to 64-bit, in which case you have the option to mark your assemblies so that the Windows loader can do the right thing at start up. Keep in mind that downstream dependencies have a direct impact on the overall application.
I have found that for smaller apps that don't need the benefits of x64 but need to call into some unmanaged COM components that marking the assemblies as x86 is a reasonable mitigation strategy. The same rules apply if you're making a WPF app, a Console App or an
ASP.NET app. Very likely you'll not have to deal with this stuff if you're staying managed, but I wanted to put it out there in case you bump into it.
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
I have customers who cannot launch my 32-bit applications on 10.14. This is music software that uses CoreAudio. This started happening recently after installing iMovie and perhaps some other Apple software. The error is:
My treasured 32-bit Sample Manager app and various 32-bit plugins (VST/AU) suddenly refuse to load. The only thing I can think of is that I recently helped a client to upgrade from her iPhone 7 to a 2020 iPhone SE, and since I used iMazing for the process, it needed to get new updates for iTunes for syncing. After that, I've been having this issue.
.. So, further looking around seems to point out that this is related to iTunes Software Update for Syncing with new devices. Makes sense (see above about iMazing + iTunes updates for helping a client) Well, how to solve this?
One solution I've come across is simply copying in an older MobileDevice.framework and being happy with that. But I'm not sure how to do that, since I can't simply write to /System/Library/PrivateFrameworks/MobileDevice.framework even with sudo on the terminal.
But I wonder how they have copied it. I don't have SIP disabled and I worry about this. I really need a 32-bit MobileDevice.framework and a functional Mojave 10.14.6. I cannot update to Catalina, most of my apps will then promptly stop working.
DeployMaster is capable of detecting the presence of the Microsoft .NET framework, and install it if necessary. For installation, you can bundle the .NET framework redistributable for the version of .NET that your application needs with your installer. DeployMaster automatically runs it as part of the installation, as needed.
3a8082e126