Mint Source

Code snippets, tips, and tricks…

Using Git to Sync Scripts Between PC and Pi

leave a comment »

I run my Raspberry Pi headless most of the time; Connecting to it from my PC via SSH.

Nano is a fine text editor, but I’m more comfortable in Visual Studio on my PC. I could work in Visual Studio on the PC then copy and paste into Nano on the Pi, but that’s not ideal. It’s also easy to get out of sync and loss track of what’s where.

To improve my situation I set up a Git repository in Visual Studio Team Services. To be able to access it from the Pi it’s necessary to setup Alternate Credentials.

EDIT: VSTS now supports

I can now work on my code in Visual Studio, version control it with Git and pull changes straight on to my Raspberry Pi.

First set up a Git Team Project in Visual Studio Team Service.

Then, from the Pi shell, first clone the remote repository:

git clone https://{youraccount}.visualstudio.com/DefaultCollection/_git/{yourteamproject}

Then simply pull changes to the Pi when necessary:

git pull

Your credentials will be required every time you interact with the remote repository, but you can have Git store your credentials so you only need to enter them once:

git config credential.helper store

Warning: Your password will be stored in a file in plain text. Replace ‘store’ with ‘cache’ if you’d prefer your credentials were stored in memory instead, and not persisted at all.

 UPDATE: VSTS now supports SSH connections, so there’s no need for alternative credentials or credential caching:

First, create an SSH key on the Raspberry Pi. (You could also use an existing key)

ssh-keygen -t rsa -b 4096 -C "you@email.com"

Press ‘Enter’ when prompted to accept the default file location.

Next, add the contents of ~/.ssh/id_rsa.pub to Visual Studio Team Services:

https://<you>.visualstudio.com/_details/security/keys

Finally, you can clone your git repo via SSH:

git clone ssh://{you}@{youraccount}.visualstudio.com:22/DefaultCollection/_git/{yourteamproject}

 

Advertisements

Written by Andy Lamb

January 9, 2016 at 01:28

Posted in Git, Raspberry Pi

Copy Image Scaled

leave a comment »

When an image is pasted into MS Word from the Windows clipboard, often the first task is to shrink it to the desired size. The full size image is not lost however, as zooming in on the document, printing, or enlarging the image still shows a high resolution image.

When providing a ‘Copy’ feature within your application it is possible for the image to be placed on the clipboard along with scaling information using a Metafile. When pasting into MS Word the image is already scaled as defined in the Metafile without reducing the resolution of the image.

The method below will create a Metafile given a RenderTargetBitmap commonly used in WPF applications and a scale factor.

/// <summary>
/// Create an image meta file for the supplied bitmap.
/// The meta file specifies the scaling that should be applied to the image.
/// The meta file can be placed on the clipboard and the scaled image will
/// appear when the meta file is pasted into applications such as MS Word.
/// </summary>
private static Metafile CreateMetaFile(RenderTargetBitmap rtb, double scale)
{
    Metafile metaFile = null;
    using (Graphics offScreenDeviceContext = Graphics.FromHwndInternal(IntPtr.Zero))
    {
        metaFile = new Metafile(new MemoryStream(), offScreenDeviceContext.GetHdc(), EmfType.EmfOnly);
        using (Graphics aGraphic = Graphics.FromImage(metaFile))
        {
            System.Drawing.Image image = RenderTargetBitmapToImage(rtb);
            aGraphic.SmoothingMode = SmoothingMode.HighQuality;
            aGraphic.InterpolationMode = InterpolationMode.High;
            aGraphic.DrawImage(image, new RectangleF(0, 0,
                              (image.PhysicalDimension.Width*(float) scale),
                              (image.PhysicalDimension.Height*(float) scale)));
        }
    }
    return metaFile;
}

The helper function below will create an Image from a RenderTargetBitmap.

/// <summary>
/// Convert a <see cref="RenderTargetBitmap"/> to a <see cref="System.Drawing.Image"/>
/// </summary>
private static System.Drawing.Image RenderTargetBitmapToImage(RenderTargetBitmap rtb)
{
    MemoryStream ms = new MemoryStream();
    BmpBitmapEncoder bbe = new BmpBitmapEncoder();
    BitmapFrame frame = BitmapFrame.Create(rtb);

    bbe.Frames.Add(frame);
    bbe.Save(ms);

    return System.Drawing.Image.FromStream(ms);
}

Written by Andy Lamb

January 26, 2013 at 00:22

Posted in .NET

Tagged with , , , , ,

Handling Unhandled Exceptions in .NET 4.0

leave a comment »

When an exception is thrown, the stack is unwound until a catch block is encountered that accepts the thrown exception type or a base class of it.
If a suitable catch block isn’t found in the call stack, the exception is unhandled and the application terminates immediately with a Windows error message, control of the application is lost.

To regain control, one of the .NET unhandled exception events can be hooked. These allow the developer to save the state of the application, log the exception appropriately, provide custom feedback to the user, or sometimes, stop the application from terminating.

Three unhandled exception events applicable to WPF applications are described below.

The AppDomain.CurrentDomain.UnhandledException event is raised when the entire stack for a thread has been unwound without finding an applicable exception handler. Even when using this event to catch unhandled exceptions, the application process can still be forced to terminate. Therefore, it is best to ensure unhandled exceptions cannot be raised by background threads.

static App() // Static Constructor
{
    AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
}

static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
    // Log the exception, save state, etc.
}

The method below will trigger the UnhandledException event.

static void ThrowThreadException()
{
    ThreadPool.QueueUserWorkItem(_ =>
    {
        throw new ApplicationException("Exception thrown from within a separate Thread.");
    });
}

The TaskScheduler.UnobservedTaskException event is raised when an exception occurs within a Task and is not subsequently ‘observed’ before the task is disposed. If this event isn’t handled, or the UnobservedTaskExceptionEventArgs.SetObserved method isn’t called, the exception escalation policy is triggered which terminates the application by default.

static App() // Static Constructor
{
    TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
}

static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs e)
{
    e.SetObserved(); // Stop the exception from escalating.
    // Log the exception, save state, etc.
}

The method below will trigger the UnobservedTaskException event. Garbage collection forces the unhandled exception to be thrown immediately for demonstration purposes.

static void ThrowTaskException()
{
    Task.Factory.StartNew(() =>
    {
        throw new ApplicationException("Exception thrown from within a Task.");
    });
    Thread.Sleep(500); // Ample time for the task to execute.
    GC.Collect(); // Force the task to be garbage collected.
}

The Application.DispatcherUnhandledException event is raised when an exception occurs within the UI thread but is not handled. If this event isn’t handled, or the DispatcherUnhandledExceptionEventArgs.Handled property isn’t set to true, the application is terminated.

protected override void OnStartup(StartupEventArgs e)
{
    DispatcherUnhandledException += DispatcherUnhandledExceptionHandler;
    base.OnStartup(e);
}

static void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    e.Handled = true; // Stop the exception from escalating.
    // Log the exception, save state, etc.
}

The method below will trigger the DispatcherUnhandledException event.

static void ThrowDispatcherException()
{
    throw new ApplicationException("Exception thrown from within the UI thread.");
}

Additional References
Design Guidelines for Exceptions
Handling and Throwing Exceptions

Written by Andy Lamb

April 4, 2012 at 22:22

Posted in .NET

Tagged with , , ,