📜 ⬆️ ⬇️

Cross-platform development - Windows Mobile and Windows (.NET Compact Framework, C #)

Not so many developers realize that developing applications for the Windows Mobile platform using the Compact Framework, they have a chance to build the same application under the desktop version of Windows! I myself only thought about it for a long time, assuming that there was such a possibility, but did not consider it as something, at least somewhat real.

There are several important aspects that need to be understood in order to successfully organize cross-platform builds. I spent a decent amount of time collecting the wreckage of knowledge in different parts of the network, and in some places it was so nontrivial that I decided to share some niceties with the community.


Firstly Secondly Thirdly...


First, you need to initially create an application for Windows Mobile (i.e. it is the main platform). This is really important. There are several reasons, but the main reason is that the Compact Framework is compact and that there are significantly fewer classes and properties for classes. Those. compatibility with the desktop is, but one-sided, i.e. just towards the desktop.
')
Secondly, you need to understand that the differences in the application will still be and they will have to be programmed separately. For example, the standard menu located on the bottom of Windows Mobile automatically moves up, and there Cancel and More do not look very attractive. Further, on the desktop, in principle, there is no InputPanel. Those. essentially, you need to be prepared for the #if #else #endif compiler instructions.

Thirdly, we must also prepare for the fact that there will be some restrictions regarding the design of forms. Namely, it is impossible to open the form with a visual editor when the desktop is selected as the current target - immediately in * .Designer.cs you will fly into many properties that are not supported by the mobile framework - you will have to roll back.

Fourth, you will have to manually edit the * .csproj files and see yellow triangles in the Solution Explorer - this is normal :)

Fifth, not all assemblies and neymspesy 100% work on the desktop. For example, I’m not at all sure that SQL Server Compact is built on the desktop. I did not check, so I do not promise. I know for sure that everything is fine with SQLite (although I will have to sweat a bit).

Sixth, you need to figure out how to debug the application on the desktop, because everyone knows that when building a mobile application, you must select a device, a physical or an emulator!

Let's try to deal with the basic subtleties.

Desktop target


Let's start with the fact that we have to have some project created for the Compact Framework. Create a new target through Build-> Configuration Manager:
Configuration manager

After that, add a conditional compilation symbol in the project properties:
Conditional Statement Symbol

A start. Now let's see what to do to ensure the connection of the correct assemblies in the desired target. By default, in our csproj file there are no divisions by target:

< ItemGroup >
< Reference Include ="mscorlib" />
< Reference Include ="System" />
< Reference Include ="System.Data" />
< Reference Include ="System.Drawing" />
< Reference Include ="System.Windows.Forms" />
< Reference Include ="System.Xml" />
</ ItemGroup >


* This source code was highlighted with Source Code Highlighter .


To have complete control, you need to organize something like the following trick:
< ItemGroup Condition =" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " >
< Reference Include ="mscorlib" >
< Private > False </ Private >
</ Reference >
< Reference Include ="Microsoft.WindowsMobile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" >
< SpecificVersion > False </ SpecificVersion >
< HintPath > ..\..\..\..\..\Program Files\Windows Mobile 6 SDK\Managed Libraries\Microsoft.WindowsMobile.dll </ HintPath >
</ Reference >
< Reference Include ="Microsoft.WindowsMobile.Status, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" >
< SpecificVersion > False </ SpecificVersion >
< HintPath > ..\..\..\..\..\Program Files\Windows Mobile 6 SDK\Managed Libraries\Microsoft.WindowsMobile.Status.dll </ HintPath >
</ Reference >
< Reference Include ="Microsoft.WindowsCE.Forms" >
< Private > True </ Private >
</ Reference >
< Reference Include ="System" />
< Reference Include ="System.Data" >
< Private > False </ Private >
</ Reference >
< Reference Include ="System.Windows.Forms" />
< Reference Include ="System.Drawing" />
< Reference Include ="System.Data.SQLite, Version=1.0.60.0, Culture=neutral, PublicKeyToken=1fdb50b1b62b4c84, processorArchitecture=MSIL" >
< Private > True </ Private >
< HintPath > ..\..\..\..\..\Program Files\SQLite.NET\bin\CompactFramework\SQLite.Interop.060.DLL </ HintPath >
</ Reference >
</ ItemGroup >

< ItemGroup Condition =" '$(Configuration)|$(Platform)' == 'Desktop|AnyCPU' " >
< Reference Include ="mscorlib" >
< Private > False </ Private >
< HintPath > C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll </ HintPath >
</ Reference >
< Reference Include ="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" >
< HintPath > C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll </ HintPath >
</ Reference >
< Reference Include ="System.Windows.Forms" >
< HintPath > C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll </ HintPath >
</ Reference >
< Reference Include ="System.Drawing" >
< HintPath > C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll </ HintPath >
</ Reference >
< Reference Include ="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" />
< Reference Include ="System.Data.SQLite, Version=1.0.60.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" >
< Private > True </ Private >
< HintPath > ..\..\..\..\..\Program Files\SQLite.NET\bin\System.Data.SQLite.DLL </ HintPath >
</ Reference >
</ ItemGroup >


* This source code was highlighted with Source Code Highlighter .


As you can see, we divide the ItemGroup blocks by target and specify different paths to the assemblies. I confess that it was here that I spent the longest time on my project. The correct versions were torn out of the compilation error messages;) Ie the compiler cursed that such necessary assemblies were not found and I substituted the correct values. And it was here that I tried several times to quit everything, because Such errors are very bad.

As a result of cunning manipulations with the csproj file, this nonsense is obtained in the Solution Explorer:
Solution Explorer Warnings

This is normal, because Visual Studio is not quite suitable for such perversions (although it allows them in the end).

#if #endif


When the assemblies are connected correctly, we have the opportunity for each platform to use the maximum that each of the platforms supports. Let me remind, however, that the automatic code generation of the form designer spoils us here. Therefore, it is necessary, if possible, to design everything first, and then only edit it with your hands - after all, when regenerating * .Designer.cs, the studio does not save our edits and additions to #if endif plots.

A little tricky moment. My project supports both QVGA and VGA resolution, however, in Designer.cs, the forms ClientSize property always corresponds to QVGA resolution. On the desktop, having a window of 240x268 is somehow wrong, especially when there is a VGA skin. Therefore, in the constructor after InitializeComponent (), I put the conditional compilation section:

Size vertSize = new Size(480, 560);
Size horisSize = new Size(640, 480);


[...]
InitializeComponent();
#if Desktop
this .ClientSize = vertSize;
this .FormBorderStyle = FormBorderStyle.Fixed3D;
this .MaximizeBox = false ;
this .MouseWheel += new MouseEventHandler(MainController_MouseWheel);
#endif


* This source code was highlighted with Source Code Highlighter .


As you can see, I have declared two variables of type Size. Why do you need it? Simply, for F9, I switch ClientSize to emulate a change in screen orientation. Useful when testing OnResize. And in the end, there are netbooks with 800x480, for them landscape orientation is the only possible way for everything to fit on the screen :)

You can also see that MouseWheel is also processed only on the desktop.

System.Diagnostics.Conditional


There is a convenient way to specify for which target to collect some method:
[Conditional(“Desktop”)]
public void SomeDesktopMethod()
{
}

* This source code was highlighted with Source Code Highlighter .


In this method, it is good that calls to this method may exist in the code, but if this attribute is present, calls will simply be ignored on other targets! The alternative using #if #endif assumes that wherever a call is needed, it is necessary to set a check in order to compile or not compile the call on the required platform.

Debugging on the desktop


There are two ways to debug. The first (inconvenient) is that we go to bin \ Desktop \, run the exe-file and then in the studio say Debug - Attatch to process. This method at first seems the only possible. But! There is a mega-hack, unofficial and unsupported way (which, however, works in both VS2005 and VS2008). The method is as follows:
  1. In the studio, open Tools / Options, then select Device Tools / Devices in the tree.
  2. In the drop-down menu, select the platform for which you want to organize debugging on the desktop. This will need to be repeated for all platforms where necessary.
  3. Next you need to select any of the emulators and click [Save As ...]. Conveniently call a copy of “My Computer”.
  4. Now you need to close the studio and open the% USERPROFILE% \ Local Settings \ Application Data \ Microsoft \ CoreCon \ 1.0 \ conman_ds_platform.xsl file in a text editor.
  5. In the file you need to find <DEVICE ...> element corresponding to the newly created "device"
  6. Next, add the following line - <PROPERTY ID = "IsDesktopDevice" Name = "IsDesktopDevice"> true </ PROPERTY>
    right after the <PROPERTYCONTAINER> tag.
  7. Save the conman_ds_platform.xsl and restart the studio


Well, now we have the debugger and all the goodies of desktop debugging available.

Conclusion


Well, the article lists the main pitfalls that I encountered in the process of building my project under Windows. Then everything was a matter of technique - caught exceptions and understood their reason. Among them were not found paths, which, obviously, are different on the desktop, etc., but this was all nothing compared to the initial problems.

Ps. Almost everything that was described above, I suffered as a result of a long search, and here, at the very end, when I was looking for a way to debug on the desktop, I came across a smart article by Daniel Mosa on the cross-platform compilation for the Compact Framework :) My article is not In no case is a translation, however, I cannot help but give a link to it.

Source: https://habr.com/ru/post/54539/


All Articles