我有一个简单的小命令行程序,用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位应用程序运行,尽管一切。
有没有人知道如何发生这种情况?
答案 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,无论它们构建在哪台机器上,或者运行它们。
无论如何,很抱歉让您感到烦恼,并感谢您提供让我以正确的方式看待问题的耳朵。