我们正在使用Compact Framework为Visual Studio 2005下的设备进行开发。但是我们也希望在PC上运行该软件的模拟版本(最好通过Build Configuration选择)。
然而,似乎.vsproj文件特定于设备;例如,只需更改目标就无法使用完整的.NET框架。
这有什么办法吗?我想我们可以在PC上运行紧凑的框架,但是项目仍然无法针对例如ARM处理器,或者我认为JIT编译器会为PC生成无法使用的代码?
答案 0 :(得分:3)
您可以在常规Windows(可能)中运行Compact Framework应用程序。然而,这有两个主要的潜在问题。
首先,由于在紧凑框架中缺少完整框架中存在的某些形式和控件属性,因此您的应用程序在Windows中会表现得有点奇怪。例如,在完整框架中,表单具有StartPosition属性,该属性确定表单在首次创建时在屏幕上的显示位置。紧凑框架中不存在此属性(出于显而易见的原因),因此当您在常规Windows中运行CF应用程序时,表单会选择默认的StartPosition值WindowsDefaultLocation
,这意味着设置表单的左侧和顶部属性对它们出现的位置没有影响,因此表单会随处弹出。
其次,CF中的任何Windows API PInvoke调用必须引用“coredll”,而完整框架中的相同调用引用“user32”,“winmm”等。解决此问题的一种方法是执行以下操作:
[DllImport("winmm.dll", EntryPoint="waveOutReset")]
private static extern int waveOutResetFULL(IntPtr hWaveIn);
[DllImport("coredll.dll", EntryPoint="waveOutReset")]
private static extern int waveOutResetCF(IntPtr hWaveIn);
public static int waveOutReset(IntPtr hWaveIn)
{
if (Environment.OSVersion.Platform == PlatformID.WinCE)
{
return waveOutResetCF(hWaveIn);
}
else
{
return waveOutResetFULL(hWaveIn);
}
}
还有其他方法可以做到这一点。
关于第一组问题,一种解决方案是在应用程序在常规Windows中运行时通过Reflection设置紧凑框架中缺少的属性。我认为更好的选择是将UI的所有元素封装为UserControls,每个元素托管在一个“主”UserControl上,根据需要创建和处理其他UserControl元素。然后,您可以在单个表单实例上托管单个“主”UserControl。
顺便说一下,我为一家大型造船厂编写了一个应用程序(在Windows和Windows Mobile设备上运行),它仍在使用中。实际上,当出于安全原因暂时停止在造船厂使用移动设备时,此应用程序在两种环境中运行的能力确实挽救了它的生命。
答案 1 :(得分:2)
贾里德是对的,你不能让工作室做到这一点(好吧,不是没有大量的拔头发和非常脆弱的最终结果)。此外,还有其他事情需要注意。
首先,MSIL与处理器无关,因此从这个角度来看,它不会“生成无法使用的代码”。 ARM IL与x86 IL(或MIPS或SH3)相同。事实上,CF程序集可以直接在完整的框架中使用,因为它们是retargetable(反之亦然,因为CF没有实现桌面上的所有操作码。)
也就是说,拥有一个不调用特定于设备的API的CF应用程序是非常罕见的,无论是对coredll.dll的P / Invoke还是像Microsoft.WindowsMobile.dll这样的特定于设备的程序集。在这些情况下,程序集将在运行时(无法找到本机DLL)或在加载时(无法找到引用的程序集)。
您可以(有时只需付出很大努力)解决这些问题。由你来决定它是否值得做。我的经验是,一般来说,事实并非如此。只需使用运行CE的仿真器或虚拟PC就可以减少工作量。
答案 2 :(得分:1)
我认为这样做的唯一方法是为同一个项目提供2个项目文件。一个是普通的CF,一个像普通的.Net应用程序一样工作。让项目文件同时指向CF和完整框架不是受支持的操作。
答案 3 :(得分:1)
我在一些开源代码中遇到了相关问题;我有单独的项目文件,但为了减少维护,我使用手工制作的项目文件,该文件自动包含项目树中的所有* .cs文件:
<ItemGroup>
<Compile Include="..\protobuf-net\**\*.cs" />
</ItemGroup>
这样,我不必记住将文件添加到其他构建脚本中 - 尽管我确实需要删除过时的文件(而不仅仅是从项目中删除它们)。
答案 4 :(得分:0)
我们在工作的地方这样做,而且(大部分)很好。如果你只是用它来进行仿真,你也可以处理GDI +吐出的一些粗糙边缘。您只需要识别不兼容的点并将它们推送到某种平台界面,以解决那些严重破坏问题的问题。
MusiGenesis明确表示,其中一个主要领域是你的P / Invokes。我还收集了一份非常不完整的Compact Framework / Full Framework错误列表here:
答案 5 :(得分:0)
解决方法是不使用VS.一个很好的例子是Basic4PPC软件(见here)。
这是一种VB.Net风格的编程语言(用它编写的所有应用程序都需要在设备上安装Compact Framework)。但是,重点是您只使用一个IDE,相同的源代码,但您可以编译您的应用程序以在桌面或设备上运行。有许多用户库可用,对于某些任务,您可能需要为桌面或设备使用特定的库。
该程序是用C#编写的。值得一看。
答案 6 :(得分:0)
我从不同的方向处理了类似的问题:我有一个实用工具库,可以在完整和紧凑的情况下工作,所以我使用了多个项目,但只使用了一组源文件。
完整的csproj有源文件,而紧凑的csproj有这些文件的链接。每当一个类调用一个不在compact中的方法时,我就把它作为一个部分类,所讨论的方法都包含在* .pc.cs和* .ppc.cs文件中。
将此与Marc Gravell发布的概念相结合(自动包含整个项目中的文件),它应该很容易维护。