Introduction

When you have something digital, having backups is something fundamental to keep your data safe. There are many threats over there that can destroy your data: hardware failures, viruses, natural disasters are some of the ways to make all your data vanish from one moment to the other.

I use to keep my data in several places (you can never be 100% sure Smile), making cloud and local backups, and I can say that they have saved me more than once. For cloud backups, there are several services out there and I won’t discuss them, but for local backups, my needs are very specific, and I don’t need the fancy stuff out there (disk images, copying blocked data, and so on). I just need a backup that has these features:

  • Copies data in a compressed way – it would be better that it’s a standard format, like zip files, so I can open the backups with normal tools and don’t need to use the tool to restore data.
  • Allows the copy of selected folders in different drives. I don’t want to copy my entire disk (why keep a copy of the Windows installation, or the installed programs, if I can reinstall them when I need).
  • Allows the exclusion of files and folders in the copy (I just want to copy my source code, there is no need to copy the executables and dlls).
  • Allows incremental (only the files changed) or full backup (all files in a set)
  • Can use backup configurations (I want to backup only my documents or only my source code, and sometimes both)
  • Can be scheduled and run at specified times without the need of manually starting it.

With these requirements, I started to look for backup programs out there and I have found some free ones that didn’t do everything I wanted and some paid ones that did everything, but I didn’t want to pay what they were asking for. So, being a developer, I decided to make my own backup with the free tools out there.

The first requirement is a compressed backup, with a standard format. For zip files, I need zip64, as the backup files can be very large and the normal zip files won’t handle large files. So, I decided to use the DotNetZip library (https://dotnetzip.codeplex.com/), an open source library that is very simple to use and supports Zip64 files. Now I can go to the next requirements. That can be done with a normal .NET console program.

Creating the backup program

In Visual Studio, create a new Console Program and, in the Solution Explorer, right-click the References node and select “Manage NuGet packages” and add the DotNetZip package. I don’t want to add specific code for working with the command line options, so I added a second package, CommandLineParser (https://github.com/gsscoder/commandline), that does this for me. I just have to create a new class with the options I want and it does all the parsing for me:

class Options
{
    [Option(DefaultValue = "config.xml", 
      HelpText = "Configuration file for the backup.")]
    public string ConfigFile { get; set; }

    [Option('i', "incremental", DefaultValue= false,
      HelpText = "Does an increamental backap.")]
    public bool Incremental { get; set; }

    [HelpOption]
    public string GetUsage()
    {
        return HelpText.AutoBuild(this,
          (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
    }
}

To use it, I just have to pass the command line arguments and have it parsed:

var options = new Options();
CommandLine.Parser.Default.ParseArguments(args, options);

It will even give me a –help command line for help:

image

The next step is to process the configuration file. Create a new class and name it Config.cs:

public class Config
{
    public Config(string fileName)
    {
        if (!File.Exists(fileName))
            return;
        var doc = XDocument.Load(fileName);
        if (doc.Root == null)
            return;
        IncludePaths = doc.Root.Element("IncludePaths")?.Value.Split(';');
        ExcludeFiles = doc.Root.Element("ExcludeFiles")?.Value.Split(';') ?? new string[0] ;
        ExcludePaths = doc.Root.Element("ExcludePaths")?.Value.Split(';') ?? new string[0];
        BackupFile = $"{doc.Root.Element("BackupFile")?.Value}{DateTime.Now:yyyyMMddhhmmss}.zip";
        ExcludeFilesRegex =
            new Regex(string.Join("|", string.Join("|", ExcludeFiles), string.Join("|", ExcludePaths)));
    }

    public Regex ExcludeFilesRegex { get; }
    public IEnumerable IncludePaths { get; }
    public IEnumerable ExcludeFiles { get; }
    public IEnumerable ExcludePaths { get; }
    public string BackupFile { get; }
}

To make it easy to select the paths and files to be excluded, I decided to give it a Regex style and create a Regex that will match all files. For example, if you want to remove all mp3 files, you would add something like “\.mp3$” (starts with a “.”, then mp3 and then the end of the string). If you want to remove mp3 and mp4 files, you can add this: “\.mp[34]$”. For the paths, you get the same thing, but they start and end with a slash (double slash, for the regex).

With this in place, we can start our backup. Create a new class and call it Backup.cs. Add this code to it:

class Backup
{
    private readonly FileFinder _fileFinder = new FileFinder();

    public async Task DoBackup(Config config, bool incremental)
    {
        var files = await _fileFinder.GetFiles(config.IncludePaths.ToArray(), 
               config.ExcludeFilesRegex, incremental);
        using (ZipFile zip = new ZipFile())
        {
            zip.UseZip64WhenSaving = Zip64Option.AsNecessary;
            foreach (var path in files)
                zip.AddFiles(path.Value, false, path.Key);
            zip.Save(config.BackupFile);
        }
        foreach (var file in files.SelectMany(f => f.Value))
            ResetArchiveAttribute(file);
        return 0;
    }

    public void ResetArchiveAttribute(string fileName)
    {
        var attributes = File.GetAttributes(fileName);
        File.SetAttributes(fileName, attributes & ~FileAttributes.Archive);
    }
}

This class uses a FileFinder class to find all files that match the pattern we want and creates a zip file. The GetFiles method from FileFinder returns a dictionary structured like this:

  • The key is a path related to the search path. As the paths can be on any disk of your system and they can have the same names (ex C:\Temp and D:\Temp), and that would not be ok in the zip file, the paths are changed to reflect the same structure, but their names are changed to allow to be added to the zip files. That way, if I am searching in C:\Temp and in D:\Temp, the keys for this dictionary would be C_Drive\Temp and D_Drive\Temp. That way, both paths will be stored in the zip and they wouldn’t clash. These keys are used to change the paths when adding the files to the zip
  • The value is a list of files found in that path

The files are added to the zip and, after that, their Archive bit is reset. This must be done, so the incremental backup can work in the next time: incremental backups are based on the Archive bit: if it’s set, the file was modified and it should be backed up. If not, the file was untouched. This is not a foolproof method, but it works fine for most cases. A more foolproof way to do this would be to keep a log file every full backup with the last modified dates of the files and compare them with the current file dates. This log should be updated every backup. For my case, I think that this is too much and the archive bit is enough.

The FileFinder class is like this one:

class FileFinder
{
    public async Task<ConcurrentDictionary<string, List>> GetFiles(string[] paths, 
        Regex regex, bool incremental)
    {
        var files = new ConcurrentDictionary<string, List>();
        var tasks = paths.Select(path =>
            Task.Factory.StartNew(() =>
            {
                var rootDir = "";
                var drive = Path.GetPathRoot(path);
                if (!string.IsNullOrWhiteSpace(drive))
                {
                    rootDir = drive[0] + "_drive";
                    rootDir = rootDir + path.Substring(2);
                }
                else
                    rootDir = path;
                var selectedFiles = Enumerable.Where(GetFilesInDirectory(path), f => 
                     !regex.IsMatch(f.ToLower()));
                if (incremental)
                    selectedFiles = selectedFiles.Where(f => (File.GetAttributes(f) & FileAttributes.Archive) != 0);
                files.AddOrUpdate(rootDir, selectedFiles.ToList(), (a, b) => b);
            }));
        await Task.WhenAll(tasks);
        return files;
    }

    private List GetFilesInDirectory(string directory)
    {
        var files = new List();
        try
        {
            var directories = Directory.GetDirectories(directory);
            try
            {
                files.AddRange(Directory.EnumerateFiles(directory));
            }
            catch
            {
            }
            foreach (var dir in directories)
            {
                files.AddRange(GetFilesInDirectory(Path.Combine(directory, dir)));
            }
        }
        catch
        {
        }

        return files;
    }
}

The main method of this class is GetFiles. It is an asynchronous method, I will create a new task for every search path. The result is a ConcurrentDictionary, and it has to be so, because there are many threads updating it at once and we could have concurrency issues. The ConcurrentDictionary handles locking when adding data from different threads.

The GetFilesInDirectory finds all files in one directory and, after all files are found, the data is filtered according to the Regex and, if the user asks for an incremental backup, the files are checked for their archive bit set. With this set of files, I can add them to the zip and have a backup file that can be read with standard programs.

Just one requirement remains: to have a scheduled backup. I could make the program stay in the system tray and fire the backup at the scheduled times, but there is an easier way to do it: use the Windows task scheduler. You just need to open a command prompt and type the command:

schtasks /create /sc daily /st "08:15" /tn "Incremental Backup" /t
r "D:\Projetos\Utils\BackupData\BackupData\bin\Debug\Backupdata.exe -i"

That will create a scheduled task that will run the incremental backup every day at 8:15. The main program for this backup is very simple:

static void Main(string[] args)
{
    var options = new Options();
    CommandLine.Parser.Default.ParseArguments(args, options);
    if (string.IsNullOrWhiteSpace(options.ConfigFile))
        return;
    if (string.IsNullOrWhiteSpace(Path.GetDirectoryName(options.ConfigFile)))
    {
        var currentDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        if (!string.IsNullOrWhiteSpace(currentDir))
            options.ConfigFile = Path.Combine(currentDir, options.ConfigFile);
    }
    var config = new Config(options.ConfigFile);
    var backup = new Backup();
    var result = backup.DoBackup(config, options.Incremental).Result;

}

I will parse the arguments, read and parse the config file, create the backup and exit. As you can see, the last line calls DoBackup.Result. This is because the Main method cannot be async and, if I just run it without calling async, it would not wait and would exit without running the backup. Calling result, the program will wait for the task completion.

Just one issue, here – if you wait for the task schedule to fire, you will see that a console window appears, and we don’t want that this happens while we are doing something else. One way to hide the console window is to go to the app properties and set the output type as a Windows application. That will be enough to hide the console window:

image

Conclusions

As you can see, it’s not too difficult to make a backup program using open source tools we have available. This program is very flexible, small and not intrusive. It can run anytime you want and have different configuration files. Not bad, huh?

The full source code for the project is in  https://github.com/bsonnino/BackupData

Acabo de concluir uma série de vídeos sobre o uso de sensores em UWP, que publiquei no Channel 9. São vídeos curtos, com até 15 minutos cada. Vale a pena dar uma conferida e ver como usar os sensores disponíveis no Windows 10 (os programas funcionam tanto no desktop, em tablets, como no smartphone Windows 10):

https://channel9.msdn.com/Series/Windows-Development/Trabalhando-com-Sensores-em-UWP-Parte-1-Sensor-de-Luz – Sensor de Luz – Mostra como usar o sensor de luz para mudar a visualização conforme a luminosidade do ambiente

https://channel9.msdn.com/Series/Windows-Development/Trabalhando-com-Sensores-em-UWP-Parte-2-Bssola – Bússola – Mostra como usar a bússola para dizer ao usuário a sua orientação

https://channel9.msdn.com/Series/Windows-Development/Trabalhando-com-Sensores-em-UWP-Parte-3-Inclinmetro – Inclinômetro – Usa o inclinômetro para mover uma bola na tela conforme o usuário inclina seu dispositivo para a direita ou para a esquerda

https://channel9.msdn.com/Series/Windows-Development/Trabalhando-com-Sensores-em-UWP-Parte-4-Acelermetro – Acelerômetro – Usa o acelerômetro para fazer uma bola pular na tela quando se chacoalha o dispositivo

https://channel9.msdn.com/Series/Windows-Development/Trabalhando-com-Sensores-em-UWP-Parte-5-Geolocalizao – Geolocalização – Usa o sensor de localização para obter o local atual, consultar um serviço de meteorologia e saber se irá chover no seu local atual

When you have a multi-monitor device, you usually want to write code in one monitor and debug the program in another one. This is especially helpful when you want to debug some visual interface that is rendered by the code (or debug the Paint event, for WinForms apps).

But the program you’re debugging insists to open in the same monitor you are writing code. If you try to find some setting in Visual Studio to set the monitor to open the program, you won’t find any. So, what can be done in this case?

I’ve found two options, the code one, and the Windows one. Let’s start with the code option:

Add some code in the closing of the main form to save the window position and in the constructor of the form to restore the window position. This code could be used as a feature for your program: that way, the user can reposition and resize the window and the next time he opens it, it will be in the same position. If you don’t want this feature for the released version, enclose the code in the conditional compiler directive #if DEBUG ..#endif. You can check something like that for WPF in this CodeProject article: https://www.codeproject.com/Articles/50761/Save-and-Restore-WPF-Window-Size-Position-and-or-S (things should be similar for WinForms). With this code, you can move the window to the other monitor and start debugging there. Just remember to close the app normally, to save the current position. The next time you will debug the program, the window it will be in the same place.

For UWP, saving the last window position is the default behavior, so you don’t have to do anything in the code: just move the window to the new position and close it normally and everything is set.

The Windows option is very simple, but not quite at sight: when you have a multi-monitor disposition, there is a checkbox in the display settings that says “Make this my main display”. All you have to do in this case is to right click the desktop of any monitor, select “ Display settings”, select the monitor you want to open your programs, check this box and voilà, all programs will open by default on the selected monitor. The only side effect in this case is that the search bar and the system tray will move to this monitor, but I think that this is minimal and does not affect my daily use. Easy, no?

image

That way, you can edit code in one screen and run the program in the other. So, happy debugging!

Not long ago, Microsoft released its new device, the Surface Studio, a powerhorse with a 28” touch screen, with characteristics that make it a go in the wish list for every geek (https://www.microsoft.com/en-us/surface/devices/surface-studio/overview).

With it, Microsoft released the Surface Dial, a rotary wheel that redefines the way you work when you are doing some creative design (https://www.microsoft.com/en-us/surface/accessories/surface-dial). Although it was created to interact directly with the Surface Studio (you can put it on the screen and it will open new ways to work, you can also use it even if you don’t have the Surface Studio.

In fact, you can use it with any device that has bluetooth connection and Windows 10 Anniversary edition. This article will show you how to use the Surface Dial in a UWP application and enhance the ways your user can interact with your app.

Working with the Surface Dial

Work with the Surface Dial is very easy. Just open the “Manage Bluetooth Devices” window and, in the Surface Dial, open the bottom cover to show the batteries and press the button there until the led starts blinking. The Surface Dial will appear in the window:

image

Just click on it and select “Connect”. Voilà, you are ready to go. And what can you do, now? Just out of the box, many things:

  • Go to a browser window and turn the wheel, and you’ll start scrolling the page content
  • Click on the dial and a menu opens:

image

If you turn the wheel, you can change the function the wheel does:

  • Volume, to increase or decrease the sound volume of you machine
  • Scroll, to scroll up and down the content (the default setting)
  • Zoom, to zoom in and out
  • Undo, to undo or redo the last thing

The best thing here is that it works in the program you are in, no matter if it’s a Windows 10 program or no (for example, you can use it for Undo/Redo in Word or to scroll in the Chrome browser). All of this comes for free, you don’t have to do anything.

If you want to give an extra usability for your Surface Dial, you can go to Windows Settings/Devices/Wheel and set new tools for your apps. For example, if you have a data entry form and you want to move between the text boxes, you can create a Custom Tool like this:

image

That way, the user will be able to move between the boxes using the Surface Dial. Nice, no?

But what if you want to create a special experience for your user? We’ll do that now, creating a UWP program that will be able to change properties of a rectangle: change its size, position, angle or color, with just one tool: the Surface Dial.

Creating a UWP program for the Surface Dial

Initially, let’s create a UWP program in Visual Studio. You must target the Anniversary Edition. If you don’t have it, you must install Visual Studio Update 3 on your system.

Then, add the rectangle to MainPage.xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Rectangle Width="100" Height="100" Fill =" Red" x:Name="Rectangle" RenderTransformOrigin="0.5,0.5">
        <Rectangle.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="Scale" ScaleX="1"/>
                <RotateTransform x:Name="Rotate" Angle="0"/>
                <TranslateTransform x:Name="Translate" X="0" Y="0"/>
            </TransformGroup>
        </Rectangle.RenderTransform>
    </Rectangle>
</Grid>

We have added a RenderTransform to the rectangle, so we can scale, rotate or translate it later with the Surface Dial.

The next step is add some png files for the Surface Dial icons. Get some Pngs that represent Rotate, Resize, Move in X Axis, Move in Y Axis and Change Colors (I’ve got mine from https://www.materialui.co) and add them to the Assets folder in the project.

In MainPage.xaml.cs, get the Dial controller, initialize the Surface Dial menu and set its RotationChanged event handler:

public enum CurrentTool
{
    Resize,
    Rotate,
    MoveX,
    MoveY,
    Color
}

private CurrentTool _currentTool;
private readonly List<SolidColorBrush> _namedBrushes;
private int _selBrush;

public MainPage()
{
    this.InitializeComponent();
    // Create a reference to the RadialController.
    var controller = RadialController.CreateForCurrentView();

    // Create the icons for the dial menu
    var iconResize = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Resize.png"));
    var iconRotate = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Rotate.png"));
    var iconMoveX= RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MoveX.png"));
    var iconMoveY = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MoveY.png"));
    var iconColor = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Color.png"));

    // Create the items for the menu
    var itemResize = RadialControllerMenuItem.CreateFromIcon("Resize", iconResize);
    var itemRotate = RadialControllerMenuItem.CreateFromIcon("Rotate", iconRotate);
    var itemMoveX = RadialControllerMenuItem.CreateFromIcon("MoveX", iconMoveX);
    var itemMoveY = RadialControllerMenuItem.CreateFromIcon("MoveY", iconMoveY);
    var itemColor = RadialControllerMenuItem.CreateFromIcon("Color", iconColor);

    // Add the items to the menu
    controller.Menu.Items.Add(itemResize);
    controller.Menu.Items.Add(itemRotate);
    controller.Menu.Items.Add(itemMoveX);
    controller.Menu.Items.Add(itemMoveY);
    controller.Menu.Items.Add(itemColor);

    // Select the correct tool when the item is selected
    itemResize.Invoked += (s,e) =>_currentTool = CurrentTool.Resize;
    itemRotate.Invoked += (s,e) =>_currentTool = CurrentTool.Rotate;
    itemMoveX.Invoked += (s,e) =>_currentTool = CurrentTool.MoveX;
    itemMoveY.Invoked += (s,e) =>_currentTool = CurrentTool.MoveY;
    itemColor.Invoked += (s,e) =>_currentTool = CurrentTool.Color;

    // Get all named colors and create brushes from them
    _namedBrushes = typeof(Colors).GetRuntimeProperties().Select(c => new SolidColorBrush((Color)c.GetValue(null))).ToList();
    
    controller.RotationChanged += ControllerRotationChanged;
    
    // Leave only the Volume default item - Zoom and Undo won't be used
    RadialControllerConfiguration config = RadialControllerConfiguration.GetForCurrentView();
    config.SetDefaultMenuItems(new[] { RadialControllerSystemMenuItemKind.Volume });

}

The first step is to get the current controller with RadialController.CreateForCurrentView(). Then, create the icons, initialize the items and add them to the menu. For each item, there will be an Invoked event that will be called when the menu item is invoked. At that time, we select the tool we want. The last steps are to set up the RotationChanged event handler and to remove the default menu items we don’t want.

The RotationChanged event handler is

private void ControllerRotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args)
{
    switch (_currentTool)
    {
        case CurrentTool.Resize:
            Scale.ScaleX += args.RotationDeltaInDegrees / 10;
            Scale.ScaleY += args.RotationDeltaInDegrees / 10;
            break;
        case CurrentTool.Rotate:
            Rotate.Angle += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.MoveX:
            Translate.X += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.MoveY:
            Translate.Y += args.RotationDeltaInDegrees;
            break;
        case CurrentTool.Color:
            _selBrush += (int)(args.RotationDeltaInDegrees / 10);
            if (_selBrush >= _namedBrushes.Count)
                _selBrush = 0;
            if (_selBrush < 0)
                _selBrush = _namedBrushes.Count-1;
            Rectangle.Fill = _namedBrushes[(int)_selBrush];
            break;
        default:
            break;
    }
    
}

Depending on the tool we have, we work with the desired transform. For changing colors, I’ve used an array of brushes, created from the named colors in the system. When the user rotates the dial, I select a new color in the array.

Now, when you run the program, you have something like this:

image

Conclusions

As you can see, we’ve created a completely new interaction for the user. Now, he can change size, angle, position or even color with the dial, without having to select things with the mouse. That’s really a completely new experience and that can be achieved just with a few lines of code. With the Surface Dial you can give to your users a different experience, even if they are not using the Surface Studio.

The full source code for the project is at https://github.com/bsonnino/SurfaceDial.

2016 is coming to an end (What an year here in Brazil!), and we can see retrospectives everywhere. I don’t want to do a “What happened”  or “What did I do”  retrospective. Instead, I want to write about the open source projects I used along the year.

I use open source projects a lot (I don’t like to reinvent the wheel) and they help me a lot. Although many open source projects have a lot of collaborators, most of the time, they are an effort of a single developer (or a very small group of developers) that spend their own spare time to release these gems to the public, without asking anything in return (yes – they are a case of free as “free beer” and free as “freedom”). Nothing more fair than write some lines about them as a way to say “thank you”. So let’s go!

Microsoft open source projects

In the latest years, Microsoft released a lot of open source projects: Roslyn, .NET Core, Asp.NET core, Reactive Extensions, VSCode, TypeScrypt, SignalR and PowerShell are just some of the projects that can be cloned and modified as you will (do you know that Microsoft has the largest number of open source contributors to GitHub: http://www.networkworld.com/article/3120774/open-source-tools/microsoft-s-the-top-open-source-contributor-on-github.html ?).

Although releasing the core projects is something new, I’ve been using Microsoft open source code for a long time – when I started developing, their sample projects were the best way to learn how to use the technology, and this is already the case. If you haven’t checked, go to the Microsoft samples (https://github.com/Microsoft/Windows-universal-samples) to check how to use the newest technology for Windows 10.

So, the first in this retrospective is Microsoft – you can check its open source projects in https://opensource.microsoft.com/ (there were 193 projects there at the time) and in their GitHub: https://github.com/Microsoft (there were 42 pages of repositories there!).

MVVM Light

If you develop for any of the XAML technologies and don’t use the MVVM pattern, shame on you! You should be using this pattern, as it eases the separation between business rules and UI,  facilitates testing and enhances maintainability of your code.

The pattern is very easy to implement and you don’t need any special framework to use it, but using a framework will make things easier and enforce some good rules for your code. There are several MVVM frameworks out there (MVVM Light, Caliburn Micro, Calcium, MVVM Cross, Prism are some that come to my mind, now – maybe I can add to write an article about them – this can be on my resolutions for 2017 Smile), but the one I use the most is MVVM Light Toolkit (http://www.mvvmlight.net/ , source code at http://mvvmlight.codeplex.com/), a nice work from Laurent Bugnion, an old time MVP from Switzerland.

This framework is very easy to use, you must create your ViewModels derived from ViewModelBase and, when you need a command binding, you can use the RelayCommand class. For communication between ViewModels and Views, you can use the Messenger class for sending messages between them. There is a simple IoC container, so you can use dependency injection in your code (another nice feature to remove coupling).

The simplicity and ease of use is definitely a big plus in this framework and the only thing I can say now is “Thanks, Laurent” !

Json.NET

If you are adding Nuget packages to your project, this is the first project that appears in the list. If you need to process Json data (and most developers need it), you must use this project. It’s a high performance Json package and it’s even included in the template for a new Asp.Net project!

It is mainly developed by James Newton-King and you can find it in http://www.newtonsoft.com/json (source code at https://github.com/JamesNK/Newtonsoft.Json). It has a very good Json serializer/deserializer and you can even use Linq to process the Json data. If you want to see it in use, take a look at my article http://blogs.msmvps.com/bsonnino/2016/05/26/minifying-and-formatting-json-data-with-c/ or check my Json Minifier project at https://github.com/bsonnino/ProcessJson.

LightInject

There are many open source IoC containers frameworks out there, and I like very much SimpleInjector, Unity and Ninject, but the one I use most is LightInject (http://www.lightinject.net , source code at https://github.com/seesharper/LightInject), a framework developed by Bernhard Richter. It’s very fast and lightweight and it works on most platforms I use to develop. It works fine with the IoC container available in MVVM Light, and you have several ways to resolve your dependencies.

I really recommend using an IoC container to break your dependencies and make your code more robust. Although it takes some time to get used to this kind of programming, it certainly pays it off when it comes to reusing code and debugging it.

FakeItEasy

Testing, oh, Testing! Testing is like flossing – everybody knows that they should do it, but very few (I would say nobody, but that would not be fair to some poor souls) really do it. When it comes to testing, I really think that one of the worst parts is to mock objects for the tests: create fake classes that do some fake behavior seems to me like some sin I am doing – I should not be doing that or I will go to hell.

FakeItEasy (https://fakeiteasy.github.io/ , source code at https://github.com/FakeItEasy/FakeItEasy) relieves me from that sin. With it, I am able to mock objects and create behaviors that simulate what I want in my tests. The quantity of source code this library saves me is really huge! Oh, and besides all the documentation you have for it, you can also have a free book, published by Syncfusion (one other thing I really recommend – their Succinctly series, now with 103 free ebooks, have fast documentation about a number of subjects: https://www.syncfusion.com/resources/techportal/ebooks): https://www.syncfusion.com/resources/techportal/details/ebooks/fakeiteasy. The only thing I regret in this library is the lack of support for faking under Windows 8 or Windows 10 (In this case, I have to try the LightMock library and see if it fits – another resolution for 2017).

HtmlAgilityPack

By the name, you can think that this pack is for use in an ASP.NET program, but this is not the case. This framework parses HTML files, and you can use it in any .NET application. It’s wonderful when you want to do some web scraping: just load your HTML file into an HtmlDocument and you can easily get the data in it – you can parse the HTML and even change the data in it.

You can get this package at https://htmlagilitypack.codeplex.com/

DotNetZip

If you need to manipulate Zip files in a .NET program, you can use DotNetZip (https://dotnetzip.codeplex.com/). With it, you can open zip files and add new files to them, extract or list the contents of a zip. You can even use Linq to query for entries you want. The files can have password encryption, and it also supports Zip64.

MetroLog

Logging is something that I always need for my programs. When it comes to UWP, there are not many options out there. One of them is Metrolog (https://github.com/onovotny/MetroLog), a very lightweight logging framework developed by Oren Novotny, that works fine with Windows 8/8.1 or UWP.

Although lightweight, it has many features, you can configure the destination of the logs, the logging format and it’s very easy to use: just configure the logging and get a logger with LogManagerFactory.GetDefaultLogger and you can start logging. 

UWPCommunityToolkit

Although this project is under the Microsoft Github (https://github.com/Microsoft/UWPCommunityToolkit, website at https://developer.microsoft.com/en-us/windows/uwp-community-toolkit), it’s not entirely developed by Microsoft. This is a set of components developed by community developers and Microsoft employees, and  features a set of components that are not in the UWP SDK.

You get there a set of controls, like  the Hamburger menu, a Radial gauge or a listview with the “pull to refresh”, many new animations, some code helpers, like new converters or storage helpers, or even access to services like Bing, Facebook or Twitter.

This set of components can improve your UWP apps with minimal code, it’s highly recommended.

SQLite.Net

If you need some kind of structured storage in a UWP application, the best way to do it is using a Sqlite database. In this case, you should use Sqlite.NET (https://github.com/praeclarum/sqlite-net), a small ORM for SQLite databases.

It’s very easy to use and you can have a very good database to store your data in a UWP app, without having to resort to database commands. I really like ORMs, as they abstract the use of a database and use normal C# classes to store data. When you are using a local SQLite database, this ORM is really nice!

Trinet.Core.IO.Ntfs

You won’t be using this library very often, but if you want to handle Alternate Data Streams, like I did in my article here, the Trinet.Core.IO.Ntfs (https://www.codeproject.com/Articles/2670/Accessing-alternative-data-streams-of-files-on-an , source code at https://github.com/hubkey/Trinet.Core.IO.Ntfs) will help you, without the need of adding P/Invokes and working with the Win32 API.

You can check its use in my article and take a look at the ADSs in your system (it surely worth to see what’s hidden in your files).

WPFFolderBrowser

One missing component in WPF is the Folder Browser. Usual answers to this item is to add System.Windows.Forms as a reference to your project and use the Windows Forms component in the program. That’s something I really don’t like: why should I add Windows Forms to my WPF project if I don’t want to use it?

With the Vista Bridge project (now the Windows API Code Pack – https://blogs.msdn.microsoft.com/windowssdk/2009/06/12/windows-api-code-pack-for-microsoft-net-framework/), there were a lot of components that made the bridge between the Windows 32 API released by Vista and WPF.

WPFFolderBrowser (http://wpffolderbrowser.codeplex.com/) takes the work in The Code Pack and creates a Folder Browser for WPF without having to use Windows Forms.

WriteableBitmapEx

Did you ever had the need to create a bitmap from scratch? Or to take a bitmap and change it? WriteableBitmapEx (https://github.com/teichgraf/WriteableBitmapEx/) is a library to manipulate bitmaps. It extends WriteableBitmaps and adds more processing to the bitmap manipulation.

It’s really fast and easy to use, and if you need to do something with a bitmap, you should really use it.

PCLCrypto

Cryptography is something that is needed in your apps from time to time. Windows 8/8.1 and UWP have cryptographic functions that work very well, but, if you need to have portable functions between UWP and full .NET (WPF, Windows Forms or ASP.NET), you should try PCLCrypto (https://github.com/AArnott/PCLCrypto), that uses façade assemblies to the real implementations in every platform.

This way, you use the native cryptographic assemblies for every platform without having to resort to conditional compilation.

Callisto

Callisto (https://timheuer.github.io/callisto/ , source at https://github.com/timheuer/callisto) is a framework developed by Tim Heuer, a Microsoft Program Manager, and was very useful for Windows 8 apps, especially when there was no Flyout control – at that time, the best way to implement it was to use Callisto.

Now, that a Flyout control is in the SDK, there are still a lot to use in Callisto: the rating control, the numeric up/down and the custom dialog are just some I use normally. If you haven’t checked it, it’s worth giving a look at it.

Conclusions

There was a lot covered here. As you can see, I use open source a lot, and I know it’s a big effort to maintain these libraries up-to date, so I’d like to thank all the developers that maintain these libraries and release them as open source, in a way that anybody can analyze them and use them as source code examples, use them to improve their apps without asking anything in return.

And you, do you have any other library that you think it should be listed? Do you want to know more about any of these (maybe I can write an extra article about it)? If you have anything to comment, please place it in the comments section.

Introduction

On my developer work, there are some tools that make my job much easier and I use them on a daily basis and miss them when I go to a computer where I don’t have them. To create code, I think that there’s no better tool than Resharper (see my article about it here). For debugging code, the equivalent is OzCode (http://oz-code.com/). I’ve been an OzCode user since its early betas (it was called BugAid, at those days), and it’s been improving from version to version, and its features are really valuable when debugging an app.

Using OzCode

When you are creating a program, you won’t see anything about OzCode, but as soon as you start debugging your program, OzCode appears and start to shine. One of my favorite features there is what they call Reveal (but I call this “Show me what I want”). Here’s the problem: if I have a list of items and I open it, all I see is something like this:

image

This is not what I want. As you can see, I have a list of 91 customers, and what is shown is the ToString evaluation of each one (“OzCodeTest.Customer”). I’d like to see what’s in each one of these customers and search for the ones I want. You may argue that I can create a ToString override and show what I want, but that is not intuitive, and I may change my mind while debugging (at the beginning I want to see the Id and Name, but in the middle of debugging I want to see the Name and City). And what about to find which one is located in London?

With OzCode, this is solved by simply opening one member and clicking on the star near it: the member is “favorited” and is shown in the list:

image

And what about searching? You just have to type in the search box and all items that match the search are shown:

image

If you want to create some special data, without having to create a new member, you can do so: just click on the magic wand besides the object and select “Add custom Expression”. Then, you can type the expression you want, and put the name of the new “member” after a double slash, like a comment:

[sourcecode language='csharp'  gutter='false']
[obj].City == “London” // IsFromLondon
[/sourcecode]

And it will appear on the list of members, where you can even make it as a favorite:

image

And if I only want to see the customers from London? Just click on the magic wand and select “Edit Filter”. Then, type the filter “[obj].City == “London””. The list of customers is filtered to show only the ones whose city is London:

image

One other thing that you can do here is to compare versions of the two lists: how many times do you need to know what changed between two points in the debugging? It’s very easy to find out. Just stop on the first point and click on the magic wand and select “Compare/Save value”. This will open a window to confirm. Confirm and continue running until the second point. Then click on the magic wand again and select “Compare/Compare with saved value”. A window appears and you can compare the two values. If you want to show only the differences, just click “Show differences only”:

image

Instant logging

The inspector window on steroids is very nice, but there is more help for our debugging. For me, it’s very common to need some logging in the code, to see what’s happening. I have to add a logging library, add code to log data and then analyze all logs in a separate tool. Too much work and sometimes I miss what I was expecting. So I must add a little more logging, repeat and rinse. Very cumbersome. With OzCode, all I have to do is to select the variable I’m interested, click on the yellow note icon that appears on the left and select Trace value of {variable}. That will add a new trace point that will log the value I’m interested to see.

 

image

When you run the program, you can see the number of messages traced in the bottom of the window, near the yellow note.

image

When you stop the program, you can see all messages sent in the Tracepoint viewer window:

image

There you can search for something, export the data to Excel, csv or text, so you can have a file to analyze later. Two nice features there are the Thread Id and the Stack trace. Often it’s difficult to debug multi-threading programs, when you go step by step, it’s difficult to follow the code, as the same code can be reached by different threads. If you click in the arrow next the thread Id, you will see from which threads this code was logged, and filter only some of them:

image

When you filter one thread, you can get only the messages that come from that thread:

image

The other thing that is nice is the stack trace. I always have the question: “How did the code reached here?”. The stack trace answers this:

image

Nice, no?

Swami sees all, the past and the future

If you take a look at the figure below, you will see a glimpse of the past and the future:

image

Just above line 16, you will see that we are working with the “ALFKI” customer. In line 18, you can see that the customer’s city is Berlin. OzCode will show you the following line dimmed – that line won’t be executed and the execution will go to line 20, where there is the arrow. You can also see that the second part of the If won’t be executed (it’s crossed out). You also can see the red X near the line, indicating it is false.

If you click on the glasses near the line, you will see more info:

image

You can have a lot of info about your data and how you reached there.

Exception handling

One thing that bothers me regarding exceptions is when I get an exception buried inside a bunch of Inner Exceptions. I must drill down the exception until I find something that is valuable. OzCode makes this a lot easier: when an exception is thrown, something like this one is shown:

image

You can see the exception that occurred above the line (in the code, above line 17), with four icons:

  • The first one will open the exception box – it is showing that there are two nested exceptions
  • The second one will toggle break in this kind of exception
  • The third one will go to the line where the exception occurred
  • The fourth one will search for help on Google, StackOverflow, Yahoo or Bing

If you click on the first icon or in the icon on the left of the line, it will open the exception box:

image

On the top, you will see a breadcrumb of the exception. You can click on any exceptions there and it will show you all the data for that exception and you can go to where the exception was thrown or where the exception was handled. You can also search for help in this window.

Another exception helper is the exception prediction. If you are stepping through code that will generate an exception, you get something like this:

image

You can click on the icon and skip the line, thus not throwing the exception or, if you are using Visual studio 2015, you can even edit the code and continue:

image

That’s really a great way to make your code more solid proof!

Conclusion

As you can see, OzCode gives you a lot of help for your debugging, I received a free copy due to the fact I’m a Microsoft MVP, but I really enjoy using it. If you want to try it by yourself, you can download a free version at http://oz-code.com. Happy debugging!

I’m sure that you have had this scenario at least once: you download a file from the internet and try to run it and it doesn’t work fine. If it is a CHM file, the help file doesn’t open the content:

image

 

If it’s an executable, it will show a message telling you that you got it from an unreliable source or, even worse, it stays there and does nothing. A client of mine set me a zip with some files to install. I downloaded the zip, unzipped it and tried to run and nothing happened. The only thing I could do is to open Task Manager and kill the Explorer process.

This is caused by a mechanism Windows has to lock files that come from the internet and can harm your computer. If it is a zipped file and you unzip it with Explorer, all extracted files will be protected with this mechanism. If you right click the file in Explorer, select Properties and check on the “Unlock” box, everything runs fine. The file is unlocked.

image

image

But what is this protection mechanism and how can we check if the file is protected and unprotect it?

The mechanism used is called “Alternate Data Streams” (ADS), and it’s a way that NTFS has to add extra data in a file. This data is not shown when you open a file and is size is not added to the total file size, but the data is there, hidden and taking disk space. If you open a command line prompt window and do a Dir /R command, you can see these alternate streams:

image

In the image above, you can see two lines for each file. The first one is the “real” file, and the second one is the “hidden” file. You can see that the “hidden” file has the same name of the “real” file and a complement after the colon. The Zone.Identifier:$DATA is the alternate stream for the file. It may have any name and can have any size (it can even be larger than the “real” file) and it’s a very effective way to hide information – if you open a file, you won’t see any trace of the alternate data stream. But, with great power comes great responsibility, and that can also be used for evil purposes – it can hide things the user is not aware and would not want in his computer.

For our blocked files, we know that they have a ADS, named Zone.Identifier. But what’s in the files? To show the contents of an ADS, you cannot use the normal tools. You can use Powershell to open them. For example, if you open a Powershell command line (se Window+X, then select “Windows Powershell”, you can type

Get-Content -Path .\Web_Servers_Succinctly.pdf -Stream Zone.Identifier

And it will show the contents of the file:

image

We can see that this file was transferred from Zone=3. From here we can see that 3 is URLZONE_INTERNET, the file came from the internet. So that’s what is blocking the file. It we unblock the file, here’s what we get when we query the streams in the file:

image

We have changed the ZoneId to 4, URLZONE_UNTRUSTED. This is enough to unblock the file.

Manipulating ADSs with C#

Now we know the mechanism behind Windows protection and we can create a C# program that unblocks all files in a directory. There is no API to access file streams in .NET, so you must resort to Win32 P/Invoke. The functions NtfsFindFirstStream and NtfsFindNextStream enumerate all streams in a file. DeleteFile will delete a stream, and CreateFile will create and add the stream.

Fortunately, we don’t have to work with this functions, as a brave developer has created a library to handle ADS in .NET (https://github.com/RichardD2/NTFS-Streams) and we can add it from Nuget. We will create a program to list, show contents or delete alternate streams with C#.

In Visual Studio, create a new Console application. Right click in the References node and select Manage Nuget Packages. There, install Trinet.Core.IO.Ntfs.

image

Then, in Program.cs, we will start to create our program:

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        Console.WriteLine("usage: adsviewer -(l|s|d)  [streamname]");
        return;
    }
    var selSwitch = ProcessSwitches(args);
    if (selSwitch == null)
        return;
    var parameters = args.Where(a => !a.StartsWith("-"));
    string fileName = ".";
    if (parameters.Count() > 0)
        fileName = parameters.First();
    var streamName = parameters.Skip(1).FirstOrDefault();
    if (File.Exists(fileName))
        ProcessFile(fileName, streamName, selSwitch);
    else if (Directory.Exists(fileName))
        foreach (var file in Directory.GetFiles(fileName))
            ProcessFile(file, streamName, selSwitch);
    else
    {
        Console.WriteLine("error: file/folder does not exist");
        return;
    }
}

Initially, we’ve checked if the user passed any parameters. If not, we show the usage help. Then, we process the switch (the option with a hiphen), that can be a “l” (to list the stream names), a “s” (to show the content of the streams or a “d”  (to delete the streams.

Then, we get the file or folder name and the stream name. If the user didn’t pass any file name, we admit he wants to process all the streams in all files in the current directory. If he passes a name, we check if it’s a file or a folder. If it’s a folder, we will process all files in that folder.

If the user passes a stream name, we will only process that stream. If he doesn’t pass a name, we will process all streams in the file.

ProcessSwitches checks the passed switch and sees if its valid:

private static string ProcessSwitches(string[] args)
{
    var switches = args.Where(a => a.StartsWith("-"));
    if (switches.Count() > 1)
    {
        Console.WriteLine("error: you can use only one switch at a time (-l, -s, -d)");
        return null;
    }
    var selSwitch = switches.Count() == 0 ? "l" : switches.First().Substring(1);
    if (!"lsd".Contains(selSwitch))
    {
        Console.WriteLine("error: valid switches: -l(ist), -s(how contents), -d(elete)");
        return null;
    }
    return selSwitch;
}

ProcessFile will process one file. If the user passed a directory name, we enumerate all files in the directory and call ProcessFile for each file.

private static void ProcessFile(string fileName, string streamName, string selSwitch)
{
    switch (selSwitch)
    {
        case "l":
            ListStreams(fileName);
            break;
        case "s":
            ShowContents(fileName, streamName);
            break;
        case "d":
            DeleteStream(fileName, streamName);
            break;
    }
}

Then, we have three kind of processing: if the user wants to list the names, we call ListStreams:

private static void ListStreams(string fileName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
        Console.WriteLine($"    {s.Name} - {s.Size:n0}");
}

It will enumerate all streams and list their names and sizes. The second processing is to show the contents, in ShowContents:

private static void ShowContents(string fileName, string streamName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    if (!string.IsNullOrWhiteSpace(streamName) &amp;&amp; file.AlternateDataStreamExists(streamName))
    {
        AlternateDataStreamInfo s = file.GetAlternateDataStream(streamName, FileMode.Open);
        ShowContentsOfStream(file, s);
    }
    else if (string.IsNullOrWhiteSpace(streamName))
        foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
            ShowContentsOfStream(file, s);
}

If the user passed a name of a valid stream, it will show its contents. If it has not passed a name, the program will enumerate all streams and show the contents for them all. The ShowContentsOfStream method is:

private static void ShowContentsOfStream(FileInfo file, AlternateDataStreamInfo s)
{
    Console.WriteLine($"    {s.Name}");
    using (TextReader reader = s.OpenText())
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

Finally, the third kind of processing is to delete the streams. For that, we use the DeleteStreams method:

private static void DeleteStream(string fileName, string streamName)
{
    FileInfo file = new FileInfo(fileName);
    Console.WriteLine($"{file.Name} - {file.Length:n0}");
    if (!string.IsNullOrWhiteSpace(streamName) && file.AlternateDataStreamExists(streamName))
    {
        file.DeleteAlternateDataStream(streamName);
        Console.WriteLine($"    {streamName} deleted");
    }
    else if (string.IsNullOrWhiteSpace(streamName))
        foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
        {
            s.Delete();
            Console.WriteLine($"    {s.Name} deleted");
        }
}

If the user passed a valid stream name, the program will delete that stream. If he hasn’t passed a name, the program will delete all streams in the file.

That way, we arrived at the end of our program.

Conclusions

ADSs are used in many ways, to add extra data to a file. Although there are legitimate ways to use them, sometimes, that can be used to store harmful data. We have developed a tool that can list all ADSs in a file, show their contents or delete them. With it, you can analyze the data that is attached to your file and decide what to do with it. Next time you get something that came from the internet and is blocked, you can easily unblock it with this tool.

The full source code is in http://github.com/bsonnino/ADSViewer

This last part in the series will show a different kind of sensor – the Geolocation sensor. In the strict sense, we can’t call this as a sensor, because the geolocation service will get the current location from the GPS sensor if it exists. If not, it will use other methods, like the network of wifi to detect the current location.

To get the current location, you must work in a different way that we worked for the other sensors:

  • You must add the Location capability to the app manifest
  • The user must consent with the use of the current location
  • You should instantiate a new Geolocator instance (and not get one with GetDefault)
  • There is no ReadingChanged event, but StatusChanged event

Even with these changes, you will see that it’s very easy to work with the geolocation. In this post we will develop a program that gets the current location and queries a weather service to get the forecast and see if it will rain.

Will it rain?

In Visual Studio, create a blank UWP project. To query the weather, we will use an open source project that has a C# API to query the OpenWeather map (http://openweathermap.org/API), located in https://github.com/joancaron/OpenWeatherMap-Api-Net. We can add this lib by using the Nuget Package manager (right click the References node in Solution Explorer and select Manage Nuget Packages). Just search for openweather and install the lib:

image

Just one note here: the official package doesn’t support Windows 10, so you must choose a fork of the project (the third project in the list) to install.

Then, you must add the Location capability to the app manifest. On the solution Explorer, open package.appxmanifest and go to the tab Capabilities. There, check the Location box.

image

Then, in the Main window, add this XAML:

[sourcecode language=”csharp” padlinenumbers=”true”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="RainText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="30"/>
</Grid>
[/sourcecode]

In the constructor of MainPage, we must ask for the user permissions an process the response:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
InitializeLocator();
}

public enum RainStatus
{
Rain,
Sun
};

private async void InitializeLocator()
{
var userPermission = await Geolocator.RequestAccessAsync();
switch (userPermission)
{
case GeolocationAccessStatus.Allowed:
RainText.Text = "Updating rain status…";
Geolocator geolocator = new Geolocator();
Geoposition pos = await geolocator.GetGeopositionAsync();
try
{
RainText.Text = await GetRainStatus(pos) == RainStatus.Rain ?
"It’s possible to rain, you’d better take an umbrella" :
"It will be a bright an shiny day, go out and enjoy";
}
catch
{
RainText.Text = "Got an error while getting weather";
}
break;

case GeolocationAccessStatus.Denied:
RainText.Text = "I cannot check the weather if you don’t give me the access to your location…";
break;

case GeolocationAccessStatus.Unspecified:
RainText.Text = "I got an error while getting location permission. Please try again…";
break;
}
}
[/sourcecode]

If the user allows access to the location data, we get the current position with GetGeopositionAsync and then we use this position to get the rain status, using the open weather map API. The GetRainStatus method is:

[sourcecode language=”csharp”]
private async Task GetRainStatus(Geoposition pos)
{
var client = new OpenWeatherMapClient("YourPrivateId");
var weather = await client.CurrentWeather.GetByCoordinates(new Coordinates()
{
Latitude = pos.Coordinate.Point.Position.Latitude,
Longitude = pos.Coordinate.Point.Position.Longitude
});
return weather.Precipitation.Mode == "no" ? RainStatus.Sun : RainStatus.Rain;
}
[/sourcecode]

To use the OpenWeather API, you must register with the site and get an API key. For low usage, the key and usage is free. You can register at http://openweathermap.org/appid

When you run the program, you are able to know if you will need to take an umbrella to go out:

image

Conclusions

As you could see, working with sensors is very easy and it can offer a better experience for your users. You can integrate them with your apps in many different ways. In this post, I’ve shown how to use the weather API to query if it will rain in your location, a simple, but useful program.

All source code for this project is in https://github.com/bsonnino/GeoLocation

In the previous posts (Light sensor, Compass and Inclinometer), I’ve shown how to use some sensors in a UWP app. In this post, I’ll show how to use another sensor, the accelerometer. The accelerometer will measure the acceleration of the device. This measure is very useful to see when the device is moved.

This sensor will show the acceleration in the three axis, X, Y and Z, and has a particularity: as it will show the forces that the device is submitted, its measure usually is not 0, because the device is always submitted to the gravity force (unless you take it to the space). The normal measure for the standing device is 1, the gravity force. When you move it, the measure should be different than 1.

Making a ball jump in UWP

For this post, I will develop a program that shows a ball at the bottom of the window, and when the user shakes the device, the ball jumps, using an animation. The stronger the shake, the ball will jump higher.

The sensor gives three measures, but I am not interested in the acceleration in every axis. I just want the magnitude of the acceleration, and that’s given by this formula:

[sourcecode language=”text”]
magnitude = sqrt(x^2 + y^2 + z^2)
[/sourcecode]

The magnitude of the acceleration is the square root of the sum of the squares of the three measures.

With this information, we can start our program. Create a new blank UWP solution. In the main page, change the main element to a Canvas and add an ellipse to it:

[sourcecode language=”xml”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of MainPage, add the code to position the ball, get the accelerometer and add the ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var accelerometer = Accelerometer.GetDefault();
if (accelerometer == null)
{
return;
}
accelerometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var magnitude = Math.Sqrt(
e1.Reading.AccelerationX * e1.Reading.AccelerationX +
e1.Reading.AccelerationY * e1.Reading.AccelerationY +
e1.Reading.AccelerationZ * e1.Reading.AccelerationZ);
if (magnitude &gt; 1.5)
JumpBall(magnitude);

});
};
};
}
[/sourcecode]

The code is very similar to the ones in the previous posts: we set the ball position to the bottom of the window and then set the ReadingChanged event handler. This handler gets the magnitude of the reading and then, if the magnitude is greater than 1.5G, it calls JumpBall, to make the ball jump. The code for JumpBall is:

[sourcecode language=”csharp”]
private void JumpBall(double acceleration)
{
var da = new DoubleAnimation()
{
From = ActualHeight-80,
To = ActualHeight-80-acceleration * 200,
AutoReverse = true,
Duration = new Duration(TimeSpan.FromSeconds(1))
};
Storyboard.SetTarget(da, Ball);
Storyboard.SetTargetProperty(da, "(Canvas.Top)");
var sb = new Storyboard();
sb.Children.Add(da);
sb.Begin();
}
[/sourcecode]

We create a DoubleAnimation with the bottom of the window as the starting point, the end point is given by the magnitude of the reading. The animation is related to the Canvas.Top attached property, related to the ball. With all that set, we start the animation.

That way, when the user shakes the device, the ball jumps. Now, when you run the app and shake the device, the ball will jump.

image

Conclusions

With the accelerometer, you can give your users more interactivity, detecting when they move or shake the device and act accordingly. The accelerometer is very easy to use and can improve the games usability a lot.

The full source code for this project is in https://github.com/bsonnino/JumpingBall

In the previous two posts (Light sensor and Compass), I’ve shown how to use the sensors in a UWP app. Working with them is very easy and it can enhance the usability of your app. In this post, we willshow how to use another sensor, the Inclinometer.

This sensor is used a lot for games, as it detects the inclination of the device. That way, the user can control the game by tilting the device. Pretty cool, no? It’s note a pure sensor, as you won’t have an inclinometer in your device, but it gets its data from other two sensors, the accelerometer and the gyroscope.

The sensor usage is similar to the other sensors, and it shows three measures, Yaw (the rotation on the Z axis), Pitch (rotation on the X axis) and Roll (rotation on the Y axis):

inclinometer

(source – https://msdn.microsoft.com/en-us/windows/uwp/devices-sensors/sensors)

Playing with a ball in UWP

To show the usage f an inclinometer, we will create a project that can be a starting point for a game. We will draw a ball in the window and, depending on how the user tilts the device, the ball will move faster or slower, to the left and to the right.

We will start creating a new UWP blank app. Change the main element in the main page to a Canvas and add a new Ellipse to it:

[sourcecode language=”xml” padlinenumbers=”true”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of the MainPage, we position the ball and add the code to initialize the inclinometer and set its ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var inclinometer = Inclinometer.GetDefault();
if (inclinometer == null)
{
return;
}
inclinometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var position = Canvas.GetLeft(Ball);
var newPosition = position + e1.Reading.RollDegrees;
if (newPosition ActualWidth – 80)
newPosition = ActualWidth – 80;
Canvas.SetLeft(Ball, newPosition);
});
};
};
}
[/sourcecode]

As you can see, this time I’m doing all the initialization in the handler of the Loaded event of the page. That’s because ActualWidth and ActualHeight of the page aren’t set before the Loaded event fires, and if I don’t use this handler, the ball would be placed in the wrong place. As we have a Canvas, we position the ball with the attached properties Left and Top. In the code behind, this is done with the static methods Canvas.SetLeft and Canvas.SetTop.

The next step is to get the Inclinometer sensor with GetDefault and set its ReadingChanged handler. It will get the current position of the ball and will set the new position depending on the Roll (number of degrees of tilt in the Y position). That way, if the user tilts more, the ball will move faster. If he tilts less, it will move slower.

With that code in place, we have our moving ball project complete and can run it. If your device has an inclinometer, you can see the ball moving. If it doesn’t have, you can use a Windows Phone and see the same app running there.

image

Conclusions

Using the inclinometer is very simple and you can provide your users a different kind of input with it, you just need to get its reading and move the elements in your app according to the tilt of the device.

The source code for this app is in https://github.com/bsonnino/MovingBall