Author Archives: purpleblob

Powershell ForEach-Object gotcha!

Are you serious Powershell !!!!?

Okay, now I’ve got that out of the way, I wrote a little Powershell command to delete the *.deleteme files as well as the folders they refer to that Nuget occasionally seems to leave behind when updating packages.

So I developed the script on the command line and all looked good so decided to turn it into a function to add to $profile.

The function kept failing with the error “Supply values for the following paraneters: Process[0]”.

This appears because my foreach looked like this

foreach 
{ 
   // some functionality
}

and even though we think that the curly brace is the block (as it is in C#) it appears we need to place the first curly brace on the same line as the foreach, thus

foreach { 
   // some functionality
}

Here's the script, when it was completed

[code language="csharp"]
function Delete-DeleteMeAndFolder
{
   ls "*.deleteme" | 
   foreach { 
      rm -Recurse -Force $_.Name.Replace(".deleteme", "")
      del $_.Name
   }
}

Running Powershell commands from you application

So, I’ve written some Powershell cmdlet’s and occasionally, might want to either use them or use Powershell built-in cmdlet’s in one of my applications. Let’s look at making this work.

Hosting Powershell

To host Powershell we include the System.Management.Automation reference (locally or from Nuget) and we can simply use

using(var ps = Powershell.Create())
{
   // add command(s) and invoke them
}

to create a Powershell host.

Calling built-in commands/cmdlet’s

As you can see, creating the Powershell host was easy enough, but now we want to invoke a command. We can write something like

ps.AddCommand("Get-Process");

foreach (var r in ps.Invoke())
{
   Console.WriteLine(r);
}

Invoke will return a collection of PSObjects, from each of these objects we can get member info, properties etc. but also the actual object returned from GetProcess, in this case a Process object. From this we can do the following (if required)

foreach (var r in ps.Invoke())
{
   var process = (Process) r.BaseObject;
   Console.WriteLine(process.ProcessName);
}

Passing arguments into a command

When adding a command, we don’t include arguments within the command string, i.e. ps.AddCommand(“Import-Module MyModule.dll”) is wrong. Instead we pass the arguments using the AddArgument method or we supply key/value pair arguments/parameters using AddParameter, so for example

ps.AddCommand("Import-Module")                 
  .AddArgument("HelloModule.dll");

// or

ps.AddCommand("Import-Module")                 
  .AddParameter("Name", "HelloModule.dll");

So the parameter is obviously the switch name without the hyphen/switch prefix and the second value is the value for the switch.

Importing and using our own Cmdlet’s

So here’s a simply Cmdlet in MyModule.dll

[Cmdlet(VerbsCommon.Get, "Hello")]
public class GetHello : Cmdlet
{
   protected override void ProcessRecord()
   {
      WriteObject("Hello World");
   }
}

My assumption was (incorrectly) that running something like the code below, would import my module then run the Cmdlet Get-Hello

ps.AddCommand("Import-Module")                 
  .AddArgument("HelloModule.dll");

ps.Invoke();

ps.AddCommand("Get-Hello");

foreach (var r in ps.Invoke())
{
   Console.WriteLine(r);
}

in fact ProcessRecord for our Cmdlet doesn’t appear to get called (although BeginProcessing does get called) and therefore r is not going to contain any result even though it would appear everything worked (i.e. no exceptions).

What seems to happen is that the Invoke method doesn’t (as such) clear/reset the command pipeline and instead we need to run the code Commands.Clear(), as below

ps.AddCommand("Import-Module")                 
  .AddArgument("HelloModule.dll");

ps.Invoke();
ps.Commands.Clear();
// the rest of the code

An alternative to the above, if one is simply executing multiple commands which have no reliance on new modules or a shared instance of Powershell, might be to create a Poweshell object, add a command and invoke it and then create another Powershell instance and run a command and so on.

With a Powershell 3 compatible System.Management.Automation we can use the following. AddStatement method

ps.AddCommand("Import-Module")                 
  .AddArgument("HelloModule.dll");
  .AddStatement()
  .AddCommand("Get-Hello");

foreach (var r in ps.Invoke())
{
   Console.WriteLine(r);
}

Importing modules into a runspace

To share the importing of modules among Powershell host instances, we could, instead look to create a runspace (which is basically an environment space if you like) and import the module into the runspace, doing something like this

var initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new [] { "HelloModule.dll" });

var runSpace = RunspaceFactory.CreateRunspace(initial);
runSpace.Open();

using(var ps = PowerShell.Create())
{
   ps.Runspace = runSpace;

   ps.AddCommand("Get-Hello");

   foreach (var r in ps.Invoke())
   {
      Console.WriteLine(r);
   }
}

In the above code, we import our modules into the initial session, from this we create our runspace and then we associated that with the our Powershell host(s) and reuse as required.

References

Windows PowerShell Host Quickstart

Environment variables in Powershell

This just demonstrates how, when you’re used to the standard Windows command prompt, Powershell can (at times) bite you.

So I was getting some Java code configured and noticed the ant script listed a different JAVA_HOME to the one I expected. In a standard Windows command prompt I would type

echo %JAVA_HOME%

and ofcourse, expect to see the folder location. So this is what I did in Powershell and instead I just got the result %JAVA_HOME% written out.

Powershell does things differently. In this case to output environment variables we need to use

echo $Env:JAVA_HOME

Doh!

To set an environment variable in Powershell we simply type

$env:JAVA_HOME="C:\Program Files\Java\jdk1.6.0_45"

References

See Windows PowerShell Tip of the Week

Where’s the Windows 10 mobile emulator?

So I’ve been working on some ideas on cross platform .NET development using Visual Studio 2015 and Xamarin. I have the Windows UWP application working fine on Windows 10 but wanted to see how it would look on Windows 10 phone – surprisingly I found the Windows 10 phone emulator didn’t exist as part of the Visual Studio installation (possibly I missed a check box when install or the likes) but it’s easy enough to get.

Just go to Downloads and tools for Windows 10 in the Other download options section there’s a Download the emulator link. From here we can download and install the Windows 10 mobile emulator.

Take a look as Test with the Microsoft Emulator for Windows 10 Mobile Test with the Microsoft Emulator for Windows 10 Mobile also which gives some useful information on using the emulator in different scenarios/configurations.

View/ViewModel resolver

In my first post on using Prism and Xamarin Forms Prism and Xamarin Forms I stated that you needed to follow the convention of views being located in a .Views. namespace and view models being located in a .ViewModels. namespace.

In fact this is not quite true. What happens is, if the ViewModelLocator.AutowireViewModel in the view is set to true, only then does Prism attempt to wire up a view model to a view and in fact the first thing it does is to look at whether the programmer has actually registered a view to a view model factory method. Only if this returns null (i.e. no factory has been supplied for a view) does it attempt the convention based approach.

Registering your View/ViewModel mapping

We can see how to register our view models with the following code snippet (this should be in your App.cs)

protected override void ConfigureViewModelLocator()
{
   base.ConfigureViewModelLocator();

   ViewModelLocationProvider.Register("XamarinTest.Views.MainPage", () => new MainPageViewModel());
}

As you can see in the above code, you need to ensure the full namespace and type name for the view, and yes it’s a magic string which is not great.

Convention based approach

Okay, so assuming no view/view model mapping has been registered for the view, we’ll now look at the convention based approach used in prism. So by default the convention based approach expects the views to be in a Views namespace and the view models to be in a ViewModels namespace, but this can be changed to suit your needs.

For example, some prefer to keep views and view models for a specific set of functionality together within the same folder or namespace as it saves jumping around a project look for each part of the specific functionality. Or maybe you find other was to layout your view/view model files which you prefer. You can assign your on Func to the ViewModelLocationProvider’s static method SetDefaultViewTypeToViewModelTypeResolver to achieve you own view model mapping.

Let’s take a look

// override this method in your App.cs file 
protected override void ConfigureViewModelLocator()
{
   base.ConfigureViewModelLocator();

   ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(AlternateResolver);
}

Next let’s write a simple implementation of a resolver which looks for matching ViewModels by simply expecting them to be in the same namespace etc. as the view

// add this method to your App.cs
private static Type AlternateResolver(Type type)
{
   var viewName = type.FullName;
   if (String.IsNullOrEmpty(viewName))
      return null;

   var viewModel = viewName + "ViewModel";

   return Type.GetType(viewModel);
}

Note: I had intended to create an assembly lookup method that would search the assembly for matching types but limitation in what we get as part of the PCL and/or Xamarin appears to have scuppered that idea, so in the above code we simply append ViewModel to the view name. Obviously if you name your views with the View suffix, such as MainPageView, then this code is rather simplistic and will expect the view model to be named MainPageViewViewModel, I’ll leave it to the reader to amend the method as required.

Prism and Xamarin Forms

Here’s the steps for getting Prism and Xamarin Forms up and running together. For this I’m using Visual Studio 2015. Refer to a previous post on how to get a Xamarin Forms application up and running in Visual Studio 2015 if you need to.

Note: I’m using the Unity container hence I’ll be demonstrating the code using Prism.Unity.Forms, there is support for alternate IoC containers such as NInject, Mef and Autofac. Prism.Unity.Forms will automatically include Prism.Core and Prism.Forms.

  • Create a Cross-Platform, Blank App (Xamarin.Forms Portable)
  • Using NuGet, install Prism.Unity.Forms (at the time of writing – you’ll need to click on the Include prerelease option), I’ve installed v6.2.0-pe5
  • For each of the projects you’ve created you’ll now need to go to each References section and add the Prism.Unity.Forms package from NuGet
  • Prism has a convention based approach to loading view model’s, so let’s create the two folders, Views and ViewModels off of the Portable project – in fact it’s the namespace that matters, so the expectation is for views to be in the Views namespace and likewise the view models should be in the ViewModels namespace.
  • Now add a MainPage.xaml file to the Views folder, so in the Portable project right mouse click, select Add | New Item and then from Cross-Platform select Forms Xaml Page, I’ve named mine MainPage
  • In the MainPage.xaml file you’ll see the Label is bound to a MainText property, so let’s now create a MainPageViewModel.cs file in the ViewModels folder to act as our view model for this page (the default convention is for the view model for a view to be named after the view with the suffix ViewModel, i.e. MyView by default maps to MyViewModel).
  • To allow Prism to auto wire up view models we need to add the following to the XAML file (to the ContentPage)
    xmlns:mvvm="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    mvvm:ViewModelLocator.AutowireViewModel="True"
    
  • Derive the view model from BindableBase and implement the following code to simply get things up and running
    public class MainPageViewModel : BindableBase
    {
       public string MainText { get; } = "Hello Prism World";
    }
    

    You’ll need to add using Prism.Mvvm; to resolve the BindableBase object.

  • Remove all the code from the App constructor as the MainPage will be supplied by Prism going forward.
  • Derive your App from PrismApplication instead of Application and implement the abstract methods as below
    public class App : PrismApplication
    {
       // add these methods
       protected override void OnInitialized()
       {
          NavigationService.NavigateAsync("MainPage");
       }
    
       protected override void RegisterTypes()
       {
          Container.RegisterTypeForNavigation<MainPage>();
       }
    }
    

    You’ll need to add using Prism.Unity; to resolve PrismApplication.

    OnInitialized will automatically navigate to the “MainPage” view, the magic string maps to the type name MainPage as I’m sure you can see. But in the RegisterTypeForNavigation we can change this string mapping if preferred.

Using ConfigureAwait

By default code after an await continues on the calling thread (i.e. the thread prior to the await keyword). In many cases this is what we want to happen. Remember async methods are not necessarily run on another task/thread, but in those instances where we know that they are truly asynchronous, we might actually want our code after the await to also run in the same context (i.e. on the same background thread of the async method).

So, for the sake of argument we’ll assume we’re awaiting a Task which we know is run on a background thread. Upon completion we intend to process some results from this Task, also on a background thread. Now obviously we could do something like

private async Task Process()
{
   var results = await SomeBackgroundThreadMethod();
   await Task.Run(() => ProcessOnBackgroundThread(results);
}

We can see that if SomeBackgroundThreadMethod runs on a background thread then after the await we continue on the calling thread before again spinning up another Task to run our processing code. So we’re potentially using two background threads when in reality, if we know SomeBackgroundThreadMethod actually is running on a background thread then we could simply continue to process on this same thread.

Okay, so this is a little contrived because, as you know, the SomeBackgroundThreadMethod would itself return a Task and we could simply ContinueWith on this Task. But an alternative to ContinueWith is to call ConfigureAwait on the SomeBackgroundThreadMethod Task, such as

private async Task Process()
{
   var results = await SomeBackgroundThreadMethod().ConfigureAwait(false);
   ProcessOnBackgroundThread(results)
}

Gotchas?

  • Now the code which uses ConfigureAwait seems quite obvious, but ConfigureAwait does not magically create a Task or background thread if none existed on the return from SomeBackgroundThreadMethod. For example if SomeBackgroundThreadMethod simply returns a TaskCompletionSource, ConfigureAwait would simply end up being on the calling thread.
  • ConfigureAwait only affects code following it and within the scope of the method using it, hence in the above code once we exit the Process method all async/await calls will return to their default behaviour, it’s only code within the Process method after the await which continues on the same thread as SomeBackgroundThreadMethod.

References
Task.ConfigureAwait

Xamarin and Visual Studio 2015

I’ve used Xamarin Studio in the past, which is a nice enough environment, but I’ve far more experience with Visual Studio as well as having all my dev tools integrated with it (such as Resharper). Now with Microsoft’s purchase of Xamarin I’ve finally got access to Xamarin’s Visual Studio integrations which also means I can target more platforms in a single solution.

Unfortunately things didn’t “just work” out of the box.

I’m going to go through a few of the issues I found getting started with the Visual Studio integration and hopefully provide solutions and where I can I shall detail how I got everything up and running (assuming I actually do get everything up and running).

What versions am I using?

So I’m going to begin by stating what versions I’m using

  • Visual Studio Professional 2015 (version 14.0.25123.00 Update 2) on Windows 10. This version of Visual Studio includes the Xamarin integration.
  • On the Mac I’m running El Capitan and Xamarin Studio Community edition version 5.10.3 (build 51).

Creating a project

I wanted to jump straight into trying out a Cross-Platform Xamarin.Forms project, so from New Project select Cross-Platform, then Blank App (Xamarin.Forms Portable). I named the project XamarinTest1, obviously name yours whatever you like, but I may refer to this project name within this post.

Visual Studio asks me to choose the target and minimum platform versions for my Universal Windows application – I leave the defaults and press OK.

The project template supplies the following

  • Portable class library – uses for the shared/portable code
  • An Android targeted project
  • An iOS targeted project
  • A UWP/Universal Windows targeted project
  • A Windows 8.1 targeted project
  • A Windows phone 8.1 targeted project

Now my normal inclination is to press the Run button and see what happens…

Getting the Android project up and running

The Android project is selected as the Start-up project, but the first problem occurs.

A message box stating, “There were deployment errors. Continue?” appears. It’s only when I check the Output window that I see a more useful message “Please select a valid device before running the application”. It appears that Visual Studio does not know about the Android virtual devices.

Clicking on the Open Android Emulator Manager button showed I did have emulators set-up (if you hit this problem and no emulators exist, add some).

I found that if I restarted Visual Studio and reloaded the project, it then found the emulators and was able to run correctly.

Getting the iOS project up and running

Select the iOS project and right mouse click on it, then select Set as StartUp project.

To run the iOS application we need to have a Mac running with Xamarin Studio installed. Also we need to set the Sharing System Preferences on the Mac.

Invoke using Cmd-Space and search for Remote Login and then Sharing System Preferences. From here we tick the Remote Login option and set access to specific users.

Now run the iOS application in Visual Studio. If all goes well the iOS emulator will run on the Mac via the Xamarin agent and you can now see what it looks like on your chosen iOS device emulator.

Getting UWP project up and running

Select the UWP project and right mouse click on it, then select Set as StartUp project.

If you now run the UWP application you might get a message box with the following error message: “The project ‘XamarinTest1’ needs to be deployed before it can be started.” etc.

As the message box goes onto say, select the configuration manager and locate the UWP project, check the Build and Deploy options.

If all goes well the application should now run correctly.

Getting Windows 8.1 project up and running

Select the Windows 8.1 project and right mouse click on it, then select Set as StartUp project.

This project should simply work, without any changes required.

Getting Windows Phone 8.1 project up and running

Select the Windows Phone 8.1 project and right mouse click on it, then select Set as StartUp project.

You will need the Windows 8.1 Phone emulator running on your machine (if using Windows 10) and this in turn requires the Hyper V virtualization option on the computer’s BIOS turned on.

Running the application will result in you being asked to download/install the emulator if it’s not on your machine. It’s likely you’ll need to reboot upon completion and/or may be asked if your login user should be part of the Hyper V group – which it should. Once everything is installed correctly then you’ll see a Windows phone emulator appear when you run the application.

Conclusions

It’s unfortunate this stuff doesn’t “just work” immediately out of the box, but with a little tweaking/configuring you can get five different projects running against five different device types and now the world of cross platform C# awaits.

Addendum

Part way through writing this document I foolishly decided to update the Android SDK only to find it failed and left my installation in a non-working state. So here’s what I had to do to get the system working again.

  • Android SDK didn’t appear to be available as a separate download, so I had to install Android Studio and download the NDK seperately
  • Once installed I found the folders of the installations very different from my original install so I needed to option Visual Studio’s Tools | Options
  • Select Xamarin | Android Settings
  • Change the JDK, SDK and NDK paths

So it’s not without its pain points, but eventually I had each of the platform targeted projects running.

Creating a Mobile App on Azure

If you’re wanting a highly scalable cloud based service for mobile applications, you could use the Mobile Apps service in Azure. Mobile Apps offer authentication, data access, offline sync capabilities and more.

Creating the Mobile Apps service

Let’s jump in and simply create our Mobile Apps service.

  • Log into the Azure portal on https://portal.azure.com
  • Select New
  • Select Web + Mobile
  • Select Mobile App
  • Enter a name for your app (which needs to be unique on the azurewebsites.net domain)
  • Supply a new resource group name

Once the new application has been deployed, go to the App Services section in Azure to see the current status of your new service.

Let’s add a database

Let’s take this a little further now – a good possibility is that we need to store data in the cloud for our mobile device. So from your previously created App service, scroll down the Settings tab until you come across the “MOBILE” section and then follow these instructions to create a data connection (which includes creating and SQL Server DB or connecting to an existing one).

  • Select Data Connections from the MOBILE section
  • Press the Add button
  • Leave the default SQL Database for the Type
  • Press on the SQL Database/Configure required settings
  • If you already have an SQL database setup you can select an existing one to use or click the Create a new data base option
  • Assuming you’re creating a new database, supply a database name
  • Click the Configure required settings and supply a server name, admin login, password and set the location of the server

When completed the data connections should list your new database connection.

Easy tables

We can create simple tables and offer CRUD like API’s against our data by using an Azure feature called Easy Tables. This will allow us to use REST and JSON to carry out CRUD operations against our SQL database with no coding on the server. To create Easy Tables select your mobile app service, select the Settings tab and scroll down to the “MOBILE” section, if not already there and then do the following

  • Select the Easy tables option
  • Press the Add button and give your table a name, for example for a blog reader we might start with the list of feeds, hence the table can be Feeds, for now you might leave all the permissions as “Allow anonymous access” just to get up and running
  • You can the click “Manage schema” to add new columns

The URL to you table becomes

https://<your service name>.azurewebsites.net/tables/<your table name>

This now allows us (out of the box, with no extra coding by us on the server) get access to REST API’s to the data, so let’s assume our service name is Mobile and our table name is Feeds, we can use the following to handle basic CRUD operations

  • Create: Use a HTTP POST operation against the URL https://mobile.azurewebsites.net/tables/Feeds
  • Retreive (single item): Use a HTTP GET operation against the URL https://mobile.azurewebsites.net/tables/Feeds/id where id is an identifier which Easy Tables creates on our table by default
  • Retreive (all items): Use a HTTP GET operation against the URL https://mobile.azurewebsites.net/tables/Feeds
  • Update: Use a HTTP method “PATCH” against the URL https://mobile.azurewebsites.net/tables/Feeds/id where id is an identifier which Easy Tables creates on our table by default
  • Delete: Use a HTTP DELETE operation against the URL https://mobile.azurewebsites.net/tables/Feeds/id where id is an identifier which Easy Tables creates on our table by default

Adding authentication

Initially we created the Easy table as “Allow anonymous access”, this ofcourse would allow us to test the API quickly, but obviously leaves the data unsecured. So now let’s put in place the authentication settings.

  • If not already selected, select you Mobile App and from the settings locate the “MOBILE” section, then select Easy tables and finally select you table
  • Click the Change permissions option
  • Simply change the various permissions to Authenticated access only
  • Don’t forget to press the save button

Now if you previously wrote some code to access the table without any form of authentication, you should receive a 401 error from requests to those same services now.

At this point we will need to provide a valid authentication token from an identity provider. Azure mobile apps can be set up to use Facebook, Twitter, Microsoft Account, Google or Azure Active Directory as a trusted identity provider. Along with these providers you could also roll your own custom identity provider.

To use one of the existing providers you’re going to need to get an app and client id plus an app secret, these are usually obtained from the provider’s dev portals.

Once you have this information you can do the following

  • Go to your Azure mobile app and select the Settings tab
  • Locate the Authentication/Authorization option
  • Set the App service Authentication to On
  • Now configure the Authentication provider, in the case of the social media providers simply insert your app id and app secret (or similar) as requested

Once completed you’ll need to use a slightly different URL to access your tables (for example). As you’ll need an OAuth redirect, so we’ll have something like

https://<your service name>.azurewebsites.net/.auth/login/<your identity provider>/callback

where your identity provider would be facebook, twitter, microsoftaccount, google or aad for example.

References

What are Mobile Apps?