Rendered Obsolete
2018/02/16
2017/12/31
Xamarin.Forms on OSX
Not sure how I missed this, but Xamarin.Forms now has preview support for Mac OSX clients. This is really exciting and I hope they decide to finalize support for OSX as a first-class target.
I spend fair amount of time on OSX, so one of my biggest gripes about Forms was lack of support for a native Mac client. On Windows I can target UWP and run projects directly on Windows 10. But, on OSX I have to launch either the iOS or Android target. Not a deal breaker, but certainly cumbersome.
MvvmCross promises to be a Xamarin.Forms-like MVVM framework that targets more platforms. But, it seems OSX clients are languishing as a low-priority concern for that project.
I found the solution in the xamarin forums. Need to change the initialization of NSApplication in Main.cs:
Giving me a working- albeit embarrassingly trivial- app:
I spend fair amount of time on OSX, so one of my biggest gripes about Forms was lack of support for a native Mac client. On Windows I can target UWP and run projects directly on Windows 10. But, on OSX I have to launch either the iOS or Android target. Not a deal breaker, but certainly cumbersome.
MvvmCross promises to be a Xamarin.Forms-like MVVM framework that targets more platforms. But, it seems OSX clients are languishing as a low-priority concern for that project.
Working Client
The xamarin blog's instructions mostly worked. I added a Cocoa app with the latest version of Xamarin.Forms on nuget (2.5.0) to my Forms solution, and made the required changes.
Everything built, but when I launched it I got a System.NullReferenceException:
1: Xamarin.Forms.Platform.MacOS.FormsApplicationDelegate.UpdateMainMenu() in
2: Xamarin.Forms.Platform.MacOS.FormsApplicationDelegate.DidFinishLaunching(Foundation.NSNotification notification) in
3: mobile_app.OSX.AppDelegate.DidFinishLaunching(Foundation.NSNotification notification) in /Users/jake/jade/jade/mobile_app/mobile_app.OSX/AppDelegate.cs:33
4: AppKit.NSApplication.NSApplicationMain() in
5: AppKit.NSApplication.Main(string[] args) in /Users/builder/data/lanes/5489/c4240f3f/source/xamarin-macios/src/AppKit/NSApplication.cs:100
6: mobile_app.OSX.MainClass.Main(string[] args) in /Users/jake/jade/jade/mobile_app/mobile_app.OSX/Main.cs:12
I found the solution in the xamarin forums. Need to change the initialization of NSApplication in Main.cs:
1: static void Main(string[] args)
2: {
3: NSApplication.Init();
4: NSApplication.SharedApplication.Delegate = new AppDelegate();
5: NSApplication.SharedApplication.MainMenu = new NSMenu(); // FIX
6: NSApplication.Main(args);
7: }
Line 5 is the added line.Giving me a working- albeit embarrassingly trivial- app:
2017/12/25
Windows 10 IoT Core on Raspberry Pi 3
Following up on my last post, finally got around to trying to install IoT Core on my actual Raspberry Pi device:
My development machine is a 15" Macbook Pro running OSX High Sierra (10.3.2). Wasn't able to get a Windows 10 VM in VirtualBox to recognize the SD card slot in my adapter (the otherwise fantastic Satechi type-C multi-port adapater), so started looking for how to flash the image without using IoT Core Dashboard.
ffu2img (https://github.com/t0x0/random/wiki/ffu2img) can be used to convert the ffu to an img file usable with dd found on OSX (and Linux, etc.).
Ensure you're using Python 2.7 and convert the image:
I had trouble getting those instructions to work with my card/reader. No matter what, dd failed with "Operation not permitted". In the end I had to:
Using df can see several partitions were created (/dev/disk2s1, disk2s2, disk2s3, and disk2s6) on the SD card. Once inserted in the Raspberry Pi device and powered on, IoT Core should boot.
My development machine is a 15" Macbook Pro running OSX High Sierra (10.3.2). Wasn't able to get a Windows 10 VM in VirtualBox to recognize the SD card slot in my adapter (the otherwise fantastic Satechi type-C multi-port adapater), so started looking for how to flash the image without using IoT Core Dashboard.
Image Preparation
Microsoft has some docs about using dism instead of Dashboard. From the IoT Core download page you can obtain an iso file containing an msi that by default installs the image to: C:\Program Files (x86)\Microsoft IoT\FFU\RaspberryPi2\flash.ffu
ffu2img (https://github.com/t0x0/random/wiki/ffu2img) can be used to convert the ffu to an img file usable with dd found on OSX (and Linux, etc.).
Ensure you're using Python 2.7 and convert the image:
python ffu2img.py PATH/flash.ffu
Resulting in a flash.img file in the same location as the ffu.Writing Image to SD Card
To write the image to an SD card I consulted the documentation at raspberrypi.org.I had trouble getting those instructions to work with my card/reader. No matter what, dd failed with "Operation not permitted". In the end I had to:
- Insert card into reader and connect reader to laptop
- Without unmounting the SD card, run:
sudo diskutil partitionDisk /dev/disk2 1 MBR "Free Space" "%noformat%" 100%
- Disconnect then reconnect the reader (above command seemed to eject the SD card)
- Write the image:
sudo dd bs=1m if=PATH/flash.img of=/dev/rdisk2 conv=sync
In my case, the SD card is /dev/disk2. /dev/disk2 and /dev/rdisk2 in the above commands should be adjusted appropriately for other cases.
IoT Core Setup
As it happens, I didn't have a USB keyboard on hand to get the device on the wifi.
Using an ethernet cable to connect the device directly to my laptop, I obtained the device's link-local address from the bottom-left of the touch screen. The device's admin portal is now accessible by pointing my laptop browser at http://169.254.236.118:8080 (default username/password is Administrator/p@ssw0rd).
In the left panel, selecting Connectivity, then Network, you can configure the wifi AP:
Initially the display was upside-down (assuming the HDMI port is "up" as when using this touchscreen case). To fix this, in the left panel pick Device Settings and towards the bottom in Display Orientation select "Landscape (Flipped)":
Using an ethernet cable to connect the device directly to my laptop, I obtained the device's link-local address from the bottom-left of the touch screen. The device's admin portal is now accessible by pointing my laptop browser at http://169.254.236.118:8080 (default username/password is Administrator/p@ssw0rd).
In the left panel, selecting Connectivity, then Network, you can configure the wifi AP:
Initially the display was upside-down (assuming the HDMI port is "up" as when using this touchscreen case). To fix this, in the left panel pick Device Settings and towards the bottom in Display Orientation select "Landscape (Flipped)":
2017/11/23
Win10 IoT Core Redux
Moments after completing my last post I noticed IoT Core running in the VM reported it had no IP address. I initially assumed I just had to fiddle with the network adapter settings, but after dong that for a while it appears I can't get networking to work under VirtualBox at all!
Rather than give up, I decided to give VMware a try.
VMware doesn't seem to be able to work directly with the VHD image I'd created- instead expecting a VMDK. I thought Hyper-V could be used to do the conversion, but it's only able to create a VHDX. It looks like VMware's vCenter Converter should be able to do it, but I couldn't get that working. In the end winimage got the job done.
Clicking through the VM setup I was again up and running with a working IoT Core VM. This time with networking.
I've learned my lesson to not celebrate prematurely.
Last step was installing IoT Core Dashboard and now I should be good to go:
Rather than give up, I decided to give VMware a try.
VMware doesn't seem to be able to work directly with the VHD image I'd created- instead expecting a VMDK. I thought Hyper-V could be used to do the conversion, but it's only able to create a VHDX. It looks like VMware's vCenter Converter should be able to do it, but I couldn't get that working. In the end winimage got the job done.
Clicking through the VM setup I was again up and running with a working IoT Core VM. This time with networking.
I've learned my lesson to not celebrate prematurely.
Last step was installing IoT Core Dashboard and now I should be good to go:
2017/11/18
Win 10 IoT Core
Recently been looking at using a Raspberry Pi 3 for a modestly work-related project.
Since the rest of our platform is running on Windows 10 IoT Enterprise (aka Windows 10 Enterprise LTSB), I thought I'd give IoT Core a look in the hopes that almost no porting would be required. The hardware compatibility list deserves special mention here because there is far more RaspPi accessories available than are actually supported by Win10.
For various reasons I'm not going to have hardware for over a month, so I'm trying to give things a whirl via virtualbox. This blog post seems to be referenced numerous places as the reference to get an x86/x64 ISO of IoT Core running in a VM. But, between using some tool from the XNA developer forums and glossing over several details I started looking for other sources.
This post from a year and a half ago gave me another view as it goes over running IoT Core in VMWare. It pointed me towards investigating VHD and dism. A series of MS blogs also gave me a bit better understanding of their usage: this, this, and this.
What follows is what I did in the end to get things running.
Start by downloading IoT Core. You want the ISO for MinnowBoard MAX or whatever else is x64. Mount that and run the msi. Some stuff is installed to c:\Program Files (x86)\Microsoft IoT\.
Next, need to create a VHD image:
Once it finishes writing, right-click the drive in Disk Management and select "Detach VHD".
Since the rest of our platform is running on Windows 10 IoT Enterprise (aka Windows 10 Enterprise LTSB), I thought I'd give IoT Core a look in the hopes that almost no porting would be required. The hardware compatibility list deserves special mention here because there is far more RaspPi accessories available than are actually supported by Win10.
For various reasons I'm not going to have hardware for over a month, so I'm trying to give things a whirl via virtualbox. This blog post seems to be referenced numerous places as the reference to get an x86/x64 ISO of IoT Core running in a VM. But, between using some tool from the XNA developer forums and glossing over several details I started looking for other sources.
This post from a year and a half ago gave me another view as it goes over running IoT Core in VMWare. It pointed me towards investigating VHD and dism. A series of MS blogs also gave me a bit better understanding of their usage: this, this, and this.
What follows is what I did in the end to get things running.
Installation
Image Creation
Start by downloading IoT Core. You want the ISO for MinnowBoard MAX or whatever else is x64. Mount that and run the msi. Some stuff is installed to c:\Program Files (x86)\Microsoft IoT\.
Next, need to create a VHD image:
- Launch Disk Management
- Action -> Create VHD
- Enter a location for the file
- Use 8 GB for "Virtual hard disk size"
- I left everything else as default
- Note the name of the drive that was created (in my case it was "Disk 1")
C:\> dism /Apply-Image /Image-File:”C:\Program Files (x86)\Microsoft IoT\MinnowBoardMax_x64\flash.ffu” /ApplyDrive:\\.\PhysicalDrive1 /SkipPlatformCheck
Where PhysicalDriveN is the "Disk N"- the VHD.Once it finishes writing, right-click the drive in Disk Management and select "Detach VHD".
VM Configuration
In VirtualBox (I'm using 5.1.26), create a new VM:
- Version "Windows 10 (64-bit)"
- Memory size 2048
- "Use an existing virtual hard disk file" and browse to the VHD
After the VM is created, right-click it and select "Settings". On the System tab check "Enable EFI (special OSes only)".
Start the VM and after brief startup you should be greeted with:
Sweet, sweet victory!
Detours
There were a few miss-steps along the way.
Despite every reference I found calling out the need to boot with EFI, I managed to overlook that by the time I finally got around to setting my VM up. Should you do the same, on startup the VM will fail immediately:
FATAL: No bootable medium found! System halted.
After that, once I enabled EFI I was dropped into a UEFI shell:
Luckily, I stubbled upon the setup guide for the MinnowBoard MAX which provided the necessary hint. Guessing that the first device listed was the correct device I tried:
Only, it wasn't there. There was only an efi file for x64- it was trying to boot a 64-bit OS. I'd followed the old blogs and picked "Windows 10 (32-bit)" when setting up the VM. Nuking that VM and setting it up as "Windows 10 (64-bit)" like in the instructions above did the trick.
Astute readers might have noticed my host OS is OSX. The Windows 10 portions were also done within the confines of VirtualBox.
Luckily, I stubbled upon the setup guide for the MinnowBoard MAX which provided the necessary hint. Guessing that the first device listed was the correct device I tried:
Shell> fs0:
fs0:> efi\boot\bootia32.efi
Only, it wasn't there. There was only an efi file for x64- it was trying to boot a 64-bit OS. I'd followed the old blogs and picked "Windows 10 (32-bit)" when setting up the VM. Nuking that VM and setting it up as "Windows 10 (64-bit)" like in the instructions above did the trick.
Astute readers might have noticed my host OS is OSX. The Windows 10 portions were also done within the confines of VirtualBox.
2017/10/24
Return to Xamarin and So Long to PCL
Working on a new project and using C# for the majority of the PC client. We need a mobile app as well, so Xamarin seemed like the logical choice to maximize code reuse.
When previously working with Xamarin I was introduced to PCL. But, I was forever running into problems with platforms I was targeting and the ones supported by packages on nuget.
Apparently well aware of its flaws Microsoft has since deprecated PCL in favor of .Net Standard. We've started targeting the bleeding edge .Net Standard 2.0 since it provides the widest API coverage and meets our platform requirements. What follows is my experience getting a multi-platform (initially just Android and UWP) Xamarin.Forms app using .Net Standard 2.0 building and running with Visual Studio 2017 Community.
When previously working with Xamarin I was introduced to PCL. But, I was forever running into problems with platforms I was targeting and the ones supported by packages on nuget.
Apparently well aware of its flaws Microsoft has since deprecated PCL in favor of .Net Standard. We've started targeting the bleeding edge .Net Standard 2.0 since it provides the widest API coverage and meets our platform requirements. What follows is my experience getting a multi-platform (initially just Android and UWP) Xamarin.Forms app using .Net Standard 2.0 building and running with Visual Studio 2017 Community.
Creation
Using the VS 2017 new project wizard, there's currently no obvious way to create a Xamarin app that uses .Net Standard 2.0. Under Other Languages, Visual C#, there's Cross Platform App (Xamarin). Next, for UI Technology choose Xamarin.Forms and Code Sharing Strategy choose Portable Class Library (PCL). From there the following two links got me started converting the PCL project to .Net Standard:Building
Building for the first time resulted in a bunch of errors similar to the following: obj\Debug\netstandard2.0\mobile_app.AssemblyInfo.cs(14,12,14,54): error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute
obj\Debug\netstandard2.0\mobile_app.AssemblyInfo.cs(15,12,15,60): error CS0579: Duplicate 'System.Reflection.AssemblyConfigurationAttribute' attribute
obj\Debug\netstandard2.0\mobile_app.AssemblyInfo.cs(16,12,16,58): error CS0579: Duplicate 'System.Reflection.AssemblyDescriptionAttribute' attribute
To fix this, I need to remove Properties/AssemblyInfo.cs from the project.
App.xaml.cs(6,7,6,14): error CS0246: The type or namespace name 'Xamarin' could not be found (are you missing a using directive or an assembly reference?)
MainPage.xaml.cs(6,7,6,14): error CS0246: The type or namespace name 'Xamarin' could not be found (are you missing a using directive or an assembly reference?)
App.xaml.cs(10,32,10,43): error CS0246: The type or namespace name 'Application' could not be found (are you missing a using directive or an assembly reference?)
MainPage.xaml.cs(10,37,10,48): error CS0246: The type or namespace name 'ContentPage' could not be found (are you missing a using directive or an assembly reference?)
App.xaml.cs(19,33,19,40): error CS0115: 'App.OnStart()': no suitable method found to override
App.xaml.cs(24,33,24,40): error CS0115: 'App.OnSleep()': no suitable method found to override
App.xaml.cs(29,33,29,41): error CS0115: 'App.OnResume()': no suitable method found to override
For this, right-click VS project, Manage NuGet Packages, and add Xamarin.Forms.
error : Project 'mobile_app\mobile_app\mobile_app\mobile_app.csproj' targets '.NETStandard,Version=v2.0'. It cannot be referenced by a project that targets 'UAP,Version=v10.0.10586'.
I couldn't just build a UWP application with .NetStandard 2.0, it required upgrading Visual Studio 2017 to 15.4 and setting the Minimum Version of the UWP project to "Windows 10 Fall Creators Update" (may first need to set Target Version to the same).
Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType)
at System.Reflection.RuntimeAssembly.GetCustomAttributes(Type attributeType, Boolean inherit)
at System.Attribute.GetCustomAttributes(Assembly element, Type attributeType, Boolean inherit)
at System.Attribute.GetCustomAttribute(Assembly element, Type attributeType, Boolean inherit)
at System.Reflection.CustomAttributeExtensions.GetCustomAttribute[T](Assembly element)
at Microsoft.Build.Tasks.ProcessResourceFiles.ReadAssemblyResources(String name, String outFileOrDir)
Updating Microsoft.NETCore.UniversalWindowsPlatform package to the latest version on nuget solved this.
There's also a warning about incompatible versions of Xamarin.Forms, but for that I just removed the reference to the old assembly from the UWP project.
Running
DEP3321: To deploy this application, your deployment target should be running Windows Universal Runtime version 10.0.16299.0 or higher. You currently are running version 10.0.15063.674. Please update your OS, or change your deployment target to a device with the appropriate version.
Here we're targeting Fall Creators Update but I wasn't running it yet. Previously I would have to enroll in Windows 10 Insider Preview, but as of today Fall Creators Update is officially released.
Finally, I'm not sure if this is actually required for UWP apps, but it's needed for Android so I'll mention it here anyway. Xaml files need to be available at runtime, so right-click each and in Properties set "Build Action" to "Embedded resource".
2017/10/19
Migrating Orleans backend from Windows to Linux, AWS, and beyond
This is a draft of a post I composed in March, 2016. Only partially completed, but maybe it will be of some value to someone.
Our backend has been based on Microsoft Orleans (MS Research, GitHub) for some time. We're primarily running the entire backend- deployment and all- on Windows 7 mostly because:
- It's convenient since all developers are running Windows on their desktops
- It's easier for QA to test and operate playtests until everything is fully automated and we've got devops tools in place
- Our company is mostly a "Windows shop" anyway
- We use log4net and our App.config was specifying ColoredConsoleAppender which didn't work on Mono (switched to ConsoleAppender)
- We spawn our game servers using Process.StartInfo.UseShellExecute = true and caused an error "xdg-open: unexpected option ..." (we set UseShellExecute to false on Linux- Windows seems to require it)
- Our config file had a Windows "smell"
- It refused to startup with the version of mono that ships with Ubuntu 14.04, but installing the latest, stable version fixed that
- Hard-coded windows specific paths and commands
- Paths that were incorrect with a case-sensitive filesystem
- Asserts that were triggered by incomplete implementations
Subscribe to:
Posts (Atom)