我已经将 Windows 服务构建为“Any CPU”。为什么它在我的 64 位机器上以 32 位模式运行?

发布于 2024-08-26 05:56:56 字数 494 浏览 4 评论 0原文

我已经将 Windows 服务构建为“Any CPU”。但是,当我在 64 位计算机上运行它时,它会以 32 位运行。我该如何修复它?我使用.NET 和 C#,我的操作系统是 Windows 2008 R2。

如果我以 x64 构建它,它会以 64 位模式正确加载。然而,“Any Cpu”——这就是我想要的——以 32 位加载,即使它运行的机器完全支持 64 位。

编辑以根据反馈添加更多信息

我们确实有第三方工具以及引用 C++ 托管程序集。它们可能是为任何 CPU 构建的,也可能不是。事实上,我知道 C++ 托管程序集仅为 x86 构建。然而,奇怪的是,如果我专门指定 x64,该进程将在 x64 中启动并工作。如果框架尝试加载 C++ 托管程序集,它将失败。我不介意这一点,因为在代码中,如果我们在 64 位模式下运行,我们不会加载 32 位托管 ++ 程序集。难道构建认为由于这里有一个 32 位程序集,它应该将启动进程(在本例中是 Windows 服务程序集)标记为 x86?

I've built a Windows service as "Any CPU". However, when I run it on my 64 bit machine it runs in 32 bit. How can I fix it? I'm using .NET and C#, and my operating system is Windows 2008 R2.

If I build it in x64 it correctly loads in 64 bit mode. However, "Any Cpu" -- which is what I want -- loads in 32 bit, even though the machine it's running on perfectly supports 64 bit.

EDIT to add more information based on feedback

We do have third party tools as well as reference a c++ managed assembly. These may or may not be built for any CPU. In fact i know that the c++ managed assembly is only built for x86. However, the odd things is that if I specifically specify x64 the process will start up and work in x64. If the framework were to attempt to load the c++ managed assembly it would fail. I don't mind this, because in the code, we do not load the 32bit managed ++ assembly if we're running in 64 bit mode. Could it be that the build figures that since there is a 32 bit assembly in here it should mark the launching process (in this case a windows service assembly) as x86?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

疑心病 2024-09-02 05:56:56

万一有人遇到我所做的同样的事情:我创建了两个新的配置设置(从调试配置复制)。由于某种原因,“Prefer32Bit”标志被设置为 true,即使项目配置页面中的复选框呈灰色且未选中

您可以通过直接从 .csproj 文件中删除该行来修复它。

  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Staging|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Staging\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>true</Prefer32Bit> <!-- REMOVE THIS LINE -->
  </PropertyGroup>

In case anybody runs across the same thing I did: I had created two new config settings (copied from the Debug config). For some reason "Prefer32Bit" flag was set to true, even though the checkbox was greyed out and unchecked in the project config page.

You can fix it by removing the line directly from the .csproj file.

  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Staging|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Staging\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>true</Prefer32Bit> <!-- REMOVE THIS LINE -->
  </PropertyGroup>
会发光的星星闪亮亮i 2024-09-02 05:56:56

有一个设置可以强制 AnyCPU 程序集在 x64 操作系统上作为 32 位运行。
使用 .Net2 x64 目录中的 ldr64.exe 检查状态:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727>ldr64.exe query
loading kernel32...done.
retrieved GetComPlusPackageInstallStatus entry point
retrieved SetComPlusPackageInstallStatus entry point
Current status is: 0x00000001

1 - 表示“以 64 位运行 AnyCPU”
0 - 表示“将 AnyCPU 作为 32 位运行”

虽然我在 .Net v4 文件夹中没有找到此类实用程序,但该设置也适用于 Net4 AnyCPU 程序集。此标志保存在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework 项下的 DWORD 注册表值 Enable64Bit 中。

此设置似乎在操作系统启动时加载,仅更改注册表值不会在重新启动之前不会影响应用程序。使用 ldr64.exe 更改标志会立即生效。

请注意,此设置是系统范围的。默认情况下,Enable64Bit 设置为 1。似乎某些应用程序将其重置为 0,并且恢复该值可能会导致该应用程序出现问题。

There's a setting that can force AnyCPU assemblies to run as 32-bit on x64 OS.
Use ldr64.exe from .Net2 x64 directory to check the status:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727>ldr64.exe query
loading kernel32...done.
retrieved GetComPlusPackageInstallStatus entry point
retrieved SetComPlusPackageInstallStatus entry point
Current status is: 0x00000001

1 - means 'run AnyCPU as 64-bit'
0 - means 'run AnyCPU as 32-bit'

Though I didn't find such utility in .Net v4 folder, the setting applies to Net4 AnyCPU assemblies as well. This flag is saved in DWORD registry value Enable64Bit under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework

This setting seems to be loaded on OS start, and changing only registry value doesn't affect applications until reboot. Changing the flag with ldr64.exe takes effect immediately.

Note that this setting is system-wide. By default Enable64Bit is set to 1. It seems that some application reset it to 0, and reverting the value back can cause problem to that app.

鯉魚旗 2024-09-02 05:56:56

感谢这个答案。我使用 CorFlags 来获取它作为 64 位运行

corflags.exe WindowService.exe /32bitpref- /32bitreq-

我使用的 CorFlags 版本是 4.0.30319.17929,我在 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools 中找到它。您可以尝试使用以下旧版本:

corflags.exe WindowService.exe /32bit-

Thanks to this answer. I use CorFlags to get it to run as 64 bit

corflags.exe WindowService.exe /32bitpref- /32bitreq-

The version of CorFlags that I used was 4.0.30319.17929, which I found in C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools. You could try the older versions with the following:

corflags.exe WindowService.exe /32bit-
两相知 2024-09-02 05:56:56

如果启动 CLR 的应用程序 exe 编译为:

  1. x64:使用 JIT 编译 x64 版本的程序集的 AnyCPU 程序集(速度慢)。 x86 程序集将收到 BadImageFormatException。
  2. x86:AnyCPU 将 JIT 组装到 x86。 x64 程序集将收到 BadImageFormatException。
  3. AnyCPU:.Net 将默认为 x86。见上文。

我经常使用入门应用程序,其中我将 .exe 显式编译为 x64 或 x86,并发布 x86 和 x86 版本的 .msi。这可能是最简单的方法 - 性能提升通常值得管理其他文件的开销。

或者,您可以在安装过程中使用 ngen,这将在安装应用程序时执行所有 JIT 操作。您会注意到应用程序的启动时间得到了改善。

另外,正如我最近在 x86 应用程序中发现的那样,.net 应用程序有 2GB 内存限制。即使您的 x86 上有 4GB 内存并且有大量剩余内存,也会发生这种情况。

If the app exe which starts the CLR is compiled as:

  1. x64: AnyCPU assemblies with use JIT to compile x64 versions of the assemblies (slow). x86 assemblies will get a BadImageFormatException.
  2. x86: AnyCPU assemblies JIT to x86. x64 assemblies will get a BadImageFormatException.
  3. AnyCPU: .Net will default to x86. See above.

I often use a starter application, where I explicitly compile the .exe as x64 or x86 and ship x86 and x86 versions of the .msi. This is probably the easiest route - The performance gain is generally worth the overhead of managing additional files.

Alternatively, you can use ngen during the setup process, which will do all the JIT stuff when the application is installed. You will notice improved start-up times for your application.

Also, as I recently discovered with x86 applications, there is a 2GB memory limit for .net applications. This occurs even when you have 4gb of ram on your x86 and have heaps of memory left over.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文