为什么编译为x86的.NET EXE作为x64运行?

时间:2012-05-21 19:36:36

标签: .net visual-studio-2010 windows-7 x86 64-bit

我有一个简单的小命令行程序,用C#编写,在.NET 4.0下运行,并用Visual Studio 10.0编译。

它的作用是从另一个供应商的Access.mdb文件中提取数据,并将其插入到Sql Server数据库中,因此我们的某个应用程序可以访问这些数据。

我们使用.NET的OleDbConnection / OleDbCommand / OleDbDataReader类,使用Microsoft.Jet.OLEDB.4.0作为数据提供者。

对我们来说这很好,直到我们尝试在64位计算机上运行。事实证明,.NET没有64位OleDb提供程序。关于分散在整个网络上的问题存在模糊,半透明的线索,讨论了不同版本的Access,或MDAC,或Office,或其他什么,以某种方式使某些人能够正常工作。

我们所做的是将项目配置为目标x86。问题就消失了。

现在它回来了,原因我根本就不明白。当我在本地机器上构建程序时,它以x86运行,但是当我在构建机器上构建它时,它以x64运行。

项目文件明确配置为以x86为目标:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>x86</PlatformTarget>
</PropertyGroup>

它是从同一个批处理文件构建的,无论是在我的机器上还是在构建机器上:

msbuild OurApp.sln /property:Configuration=Release

生成的exes 它们是x86,无论它们是在哪台机器上构建的。如果我在其中任何一个上运行dumpbin / headers,我会看到:

FILE HEADER VALUES
         14C machine (x86)
           3 number of sections
    4FBA64C8 time date stamp Mon May 21 10:52:40 2012
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
         102 characteristics
               Executable
               32 bit word machine

我机器上构建的exe转储与构建机器上构建的exe之间的唯一区别是时间戳和.pdb文件的路径。

但是,这是奇怪的事情,在我的机器上构建的exe运行得很好,一个构建在构建机器上的错误输出我们在将它构建为x64时看到的相同错误消息。

不仅如此 - 我们的程序从注册表中获取其配置,并且为了方便用户,如果找不到设置,则会创建一个。我们从HLM \ SOFTWARE \ OurName \ OurApp中读取它们并创建它们。但是,当然,因为这是一个在64位计算机上运行的32位应用程序,所以它应该是从HLM \ SOFTWARE \ WoW6432Node \ OurName \ OurApp读取和写入。

使用我的机器上构建的应用程序,它确实如此。但是构建机器上构建的应用程序,尽管是为x86编译的,并且具有表明它们应该作为x86运行的标头,从HLM \ SOFTWARE \ OurName \ OurApp和不是读取和写入来自HLM \ SOFTWARE \ WoW6432Node \ OurName \ OurApp。好像它实际上是作为一个64位应用程序运行,尽管一切。

有没有人知道如何发生这种情况?

1 个答案:

答案 0 :(得分:5)

好的,这只是加重了。

我们在.csproj文件中所拥有的是:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
</PropertyGroup>

这是采用默认配置并将其更改为目标x86的结果。

我删除了AnyCPU配置,并创建了新的x86配置,并得到了:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\x86\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
    <OutputPath>bin\x86\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
    <DebugType>pdbonly</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>

现在我可以发誓,GUI在旧配置中告诉我我在调试和发布中都是针对x86的。并且生成的可执行文件被转储为x86,并在我的机器上作为x86运行。但显然我对在什么条件下构建exe的哪个版本感到困惑,因为查看.csproj,很明显我们在构建版本时没有指定x86。

在任何情况下,使用新配置构建并运行exes,无论它们构建在哪台机器上,或者运行它们。

无论如何,很抱歉让您感到烦恼,并感谢您提供让我以正确的方式看待问题的耳朵。

相关问题