我有一个简单的命令行程序,使用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
生成的可执行文件会“说”它们是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可以正常运行,而在构建机器上构建的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位应用程序一样。
有人知道这可能是如何发生的吗?