SushiHangover

PowerShell, Learn it or Perish ;-)

master nix
Gitter

Xamarin Studio mdtool - Where is it?

I’m not sure if it is a bug or not, but older versions of Xamarin Studio (and MonoDevelop) on OS-X (prior to El Capitan) installed a mdtool shell script in /usr/local/bin but that no longer happens(?).

mdtool original/missing shell script:

#!/bin/bash
MONO_EXEC="exec mono-sgen"
EXE_PATH="/Applications/Xamarin Studio.app/Contents/Resources/lib/monodevelop/bin/mdtool.exe"
$MONO_EXEC $MONO_OPTIONS "$EXE_PATH" "$@"

So create the script with the content above and place it into a directory in your path. /usr/local/bin is fine, but I personally install my shell scripts into a $HOME/.scripts directory that is included in my path so I can backup, via a git repo, my personal scripts and distinguish what I have created verus what gets installed in the /usr/local/bin by applications such a brew

Note: Make sure that you chmod a+x mdtool in order to make it executable…

As always, have fun… ;-)

$mdtool

Xamarin Studio Tool Runner

Usage: mdtool [options] <tool> ... : Runs a tool.
       mdtool setup ... : Runs the setup utility.
       mdtool -q : Lists available tools.

Options:
  --verbose (-v)   Increases log verbosity. Can be used multiple times.
  --no-reg-update  Skip updating addin registry. Faster but results in
                   random errors if registry is not up to date.

Available tools:
- build: Project build tool
- dbgen: Parser database generation tool
- project-export: Project conversion tool
- gsetup: Graphical add-in setup utility
- archive: Project archiving tool
- account: Xamarin account tool
- mac-bundle: Mac application bundle and installer generator.

NUnit Console 2.4.8 vs 3.0 using .csproj files

When using NUnit console 2.4.x and 3.x with .csproj files, it expects a valid and fairly complete MSBuild/xbuild project to determine the assembly name, dir location, and namespace that it will test in the Library-based project (Exe-based projects are possible if you have defined the proper entry point). In this example I used NUnit 2.4.x and 3.x console as there are execution differences but the same .csproj is being used so if you are using MonoDevelop/Xamarin Studio the IDE’s built-in NUnit 2.4.x test pad will also work.

NUnit 3.0 console (Install via nuget):

mono $(MTOOLS)/nunit3-console.exe  nunit-lib/nunit-lib.csproj --config=Debug

NUnit Console Runner 3.0.5797 
Copyright (C) 2015 Charlie Poole

Runtime Environment
   OS Version: MacOSX 15.0.0.0 
  CLR Version: 4.0.30319.17020

Test Files
    nunit-lib/nunit-lib.csproj

Errors and Failures

1) Failed : nunitlib.Test.TestCase
  Expected string length 8 but was 5. Strings differ at index 0.
  Expected: "Overflow"
  But was:  "Stack"
  -----------^
at nunitlib.Test.TestCase () in <filename unknown>:line 0

Test Run Summary
    Overall result: Failed
   Tests run: 1, Passed: 0, Errors: 0, Failures: 1, Inconclusive: 0
     Not run: 0, Invalid: 0, Ignored: 0, Explicit: 0, Skipped: 0
  Start time: 2015-11-20 12:36:28Z
    End time: 2015-11-20 12:36:28Z
    Duration: 0.132 seconds

NUnit 2.4.8 (installed via Mono):

NOTE: NUnit console 2.4.x is broken due a hard-coded Windows-style Directory Separator when parsing .csproj files and creating the expected CIL/assembly location, use MONO_IOMAP to work around it. This is not a issue in 3.0.

NUnit Console 2.4.x w/o MONO_IOMAP:

nunit-console nunit-lib/nunit-lib.csproj -config=Debug
~~~~
Unhandled Exception:
System.IO.DirectoryNotFoundException: Directory "/Users/sushi/code/XamTests/nunit-lib/nunit-lib/bin\Debug" not found.
~~~~

NUnit Console 2.4.x with MONO_IOMAP:

MONO_IOMAP=all nunit-console nunit-lib/nunit-lib.csproj -config=Debug

NUnit version 2.4.8
Copyright (C) 2002-2007 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment - 
   OS Version: Unix 15.0.0.0
  CLR Version: 4.0.30319.17020 ( 4.2.1 (explicit/8862921 Thu Oct 29 17:09:16 EDT 2015) )

.F
Tests run: 1, Failures: 1, Not run: 0, Time: 0.115 seconds

Test Case Failures:
1) nunitlib.Test.TestCase :   Expected string length 8 but was 5. Strings differ at index 0.
  Expected: "Overflow"
  But was:  "Stack"
  -----------^

.csproj example used in for example:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{944946CD-39B2-4A16-A8A8-9F70F0450506}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>nunitlib</RootNamespace>
    <AssemblyName>nunit-lib</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug</OutputPath>
    <DefineConstants>DEBUG;</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <ConsolePause>false</ConsolePause>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>full</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release</OutputPath>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <ConsolePause>false</ConsolePause>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="nunit.framework">
      <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Test.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <ItemGroup>
    <None Include="packages.config" />
  </ItemGroup>
</Project>

Ref: This was my answer on StackOverflow

Xamarin Android Player / Genymotion - Foobar 101

I was really happy with Xamarin’s Android Player (XAP) on OS-X 10.11 (and 10.10.x before I upgraded). It is much better the Google’s plain-jane Android emulator, way way faster, easier setup as the images are pre-packaged Nexus images, etc… But you can not create custom images and that ends up being a problem as you need to test different configurations.

Someone recommended Genymotion and everything seemed fine, I could create custom Genymotion images and still use XAP for the basic testing…

BUT after a reboot of OS-X, everything went to @#$@#$@#. Android sessions in either player would take 10 minutes or more to start up and get to the lock screen and when I say ‘more’, I mean up to 20 minutes…or MORE. Even then, services would die, the VirtualBox instance would hang, Xamarin Studio would not connect, XAP would report that the OpenGL server is not available, Genymotion would report no IP address could be retrieved…

Removing Genymotion did not help. Deleting and re-install XAP did not help. Installing the latest VirtualBox did not help. Uninstall VirtualBox via their installer, deleting the XAP app and restarting from stratch did not help…. Removing all the original XAP Andriod images and re-downloading them did not help (I thought maybe the new VirtualBox updated them and caused a XAP issue, but no to that idea)…

Seems that I am not alone, if you started with Genymotion and later installed XAP, you could be in the same boot… after you reboot the first time. Seems Geny users call it “surviving the reboot”, if you make it past a reboot and everything is still working you should be golden, if not, your system is @#$#@$#.

I’m still looking for a solution other then re-installing the OS as some people have resorted to… I just do not have time do a fresh OS-X install so right now I can only test via actual physical devices :-(

AHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!

Xamarin Android Shared Preferences

While I do not directly recommend this technique, it seems using the PreferenceManager.GetDefaultSharedPreferences is really popular in saving values between different activities. While you can create multiple names that do not conflict between different activities, it can get messy real fast.

Instead of using GetDefaultSharedPreferences, create multiple GetSharedPreferences with different names and thus you can store values with the same names without overwriting your values from a different activity. (Again, I am not a big fan of this technique either for anything more than some simple UI preference settings, see notes at bootom of post)

i.e.

        var title = "stack"; float price = 123.34f; long weight = 23; 
        var editor = GetSharedPreferences ("MyFirstActivity", Android.Content.FileCreationMode.Private);
        var edit = editor.Edit ();
        edit.PutString ("title", title);
        edit.PutFloat ("price", price);
        edit.PutLong ("weight", weight);
        edit.Apply ();

        title = "overflow"; price = 99.99f; weight = 99;
        editor = GetSharedPreferences ("MySecondActivity", Android.Content.FileCreationMode.Private);
        edit = editor.Edit ();
        edit.PutString ("title", title);
        edit.PutFloat ("price", price);
        edit.PutLong ("weight", weight);
        edit.Apply ();

        editor = GetSharedPreferences("MyFirstActivity", Android.Content.FileCreationMode.Private);
        title = editor.GetString("title", "empty");
        price = editor.GetFloat("price", 0);
        weight = editor.GetLong("weight", 0);
        Log.Info("activity1", string.Format("{0}:{1}:{2}", title, price, weight));

        editor = GetSharedPreferences("MySecondActivity", Android.Content.FileCreationMode.Private);
        title = editor.GetString("title", "empty");
        price = editor.GetFloat("price", 0);
        weight = editor.GetLong("weight", 0);
        Log.Info("activity2", string.Format("{0}:{1}:{2}", title, price, weight));

adb logcat output:

[activity1] stack:123.34:23
[activity2] overflow:99.99:99

Notes:

Personally when I see someone saving shopping cart data, using JSON to serialize objects in and out of SharedPerferences string values, etc…, my head starts to pound in a bad way. At that time you should really start looking for an asynchronous, persistent key-value store, like Akavache.

Windows Dependency Walker for debugging missing DLLs

I was trying to track down an issue on a fresh Window 10 install with a older application that was starting but faulting on a dependancy but I was not getting the std DLL missing message…

Running the .exe under Visual Studio was getting me no where fast and than I remembered a really old program called “Dependency Walker”.

What do you know, it is still avaiable and being kept up to date, well it lists Windows 8, but it seems to also run on an Insider Windows 10 Fast Track install just fine, and Solved my problem in less then a minute…

Error: At least one required implicit or forwarded dependency was not found.    Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.     Warning: At least one delay-load dependency module was not found.   Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

Dependency Walker

Dependency Walker is a free utility that scans any 32-bit or 64-bit Windows module (exe, dll, ocx, sys, etc.) and builds a hierarchical tree diagram of all dependent modules. For each module found, it lists all the functions that are exported by that module, and which of those functions are actually being called by other modules. Another view displays the minimum set of required files, along with detailed information about each file including a full path to the file, base address, version numbers, machine type, debug information, and more.

FYI: I remember using that program on Window’s ARCH types long forgotten… and the site still has versions available (unsupported of course) for Alpha, AXP64, MIPS, and PowerPC architectures…. wow, remember when Windows ran on those ;-)

Android FileObserver example in Xamarin/C#

This is from my answer on StackOverflow from a question that got closed. As not to lose it to the SO ‘on-hold/close’ flush, I am re-posting it.

Question

How can you write an Android FileObserver in C#?

i.e. Native Java example:

FileObserver observer = new FileObserver(imageUri.getPath()) {
    public String basePath;

    @Override
    public void onEvent(int event, String path) {
        String fullPath = basePath;
        if(path != null) {
            fullPath += path;
        }
        Log.d(TAG, "FILE: "+fullPath);
    }
};
observer.basePath = imageUri.getPath();
observer.startWatching();

Answer

Create a class that inherits from Android.OS.FileObserver, you only need to implement the OnEvent() and one(+) Constructors. Its a really simple pattern after you see it once… ;-)

Quick Notes:

  • Watch on a path, if you need to filter by file, do it in the OnEvent
  • Do not let your FileObserver object get GC’d or your OnEvents will magically stop :-/
  • Remember to call StartWatching() in order to receive OnEvent calls

C# FileObserver Class:

using System;
using Android.OS;
using Android.Util;

namespace MyFileObserver
{
    public class MyPathObserver : Android.OS.FileObserver
    {
        static FileObserverEvents _Events = (FileObserverEvents.AllEvents);
        const string tag = "StackoverFlow";

        public MyPathObserver (String rootPath) : base(rootPath, _Events)
        {
            Log.Info(tag, String.Format("Watching : {0}", rootPath)); 
        }

        public MyPathObserver (String rootPath, FileObserverEvents events) : base(rootPath, events)
        {
            Log.Info(tag, String.Format("Watching : {0} : {1}", rootPath, events)); 
        }

        public override void OnEvent(FileObserverEvents e, String path)
        {
            Log.Info(tag, String.Format("{0}:{1}",path, e)); 
        }
    }
}

Example Usage:

var pathToWatch = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal);
// Do not let myFileObserver get GC'd, stash it's ref in an activty, or ...
myFileObserver = new MyPathObserver (pathToWatch);
myFileObserver.StartWatching (); // and StopWatching () when you are done...
var document = Path.Combine(pathToWatch, "StackOverFlow.txt");
button.Click += delegate {
    if (File.Exists (document)) {
        button.Text = "Delete File";
        File.Delete (document);
    } else {
        button.Text = "Create File";
        File.WriteAllText (document, "Foobar");
    }
};

adb logcat Output (when clicking on the test button):

I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite
I/StackoverFlow( 3596): StackOverFlow.txt:Delete
I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite
I/StackoverFlow( 3596): StackOverFlow.txt:Delete
I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite

iTerm2 OSX: Jump Word-wise left and right in Navigation

Jumping word-wise in the iTerm2 (3.0 beta):

  • Open the Preferences Pane
  • Goto Tab Keys
  • Create a new Key Binding with the Shortcut “⌥ + ←” and use “Send Escape Sequence” as the Action and Set “Esc + b”
  • Create a new Key Binding with the Shortcut “⌥ + →” and use “Send Escape Sequence” as the Action and Set “Esc + f”

iTerm Jump/Tab Words

OS-X El Capitan Adobe Air Installer

Have problems trying to install Adobe Air on a fresh install of OS-X 10.11? The current version of the installer that linked @ https://get.adobe.com/air/ will just hang and you will have to force quit it.

Try the latest Adobe Air Beta 20 and your problems will be sovled.

Note: This also solves the issue for older versions of Adobe CS (6 and others) failing to install properly. Install the latest Air version and retry your Adove CS install.

Git OS-X Credentials

Setting up a fresh install of El Capitan…

I installed git via homebrew:

brew git

And since it has been such a long time since I had to link git to the OS-X key chain, I totally forgot how… After way to much searching, I figured I’d post this as a reminder for at least myself ;-)

But if you installed git using homebrew, you should already have the osxkeychain helper. You can verify this by trying to run it:

git credential-osxkeychain

To tell git to use osxkeychain, simply set the global git config:

git config --global credential.helper osxkeychain

MonoDevelop.AddinMaker - CI Build and Install .mpack

Using mhutch/MonoDevelop.AddinMaker to create your Addins? If not, you should convert your Addin Project (see his “Migrating Existing Projects” notes in the repo’s README.md file)

Need to intergate building, creating the .mpack, and installing it into Xamarin Studio into your CI process?

Package your Addin to a .mpack file

xbuild PlayScript.Addin.csproj /t:CreatePackage

Install your .mpack

mdtool setup install bin/Debug/PlayScript.Addin.PlayScript.Addin_1.0.mpack

FYI: Using mhutch/MonoDevelop.AddinMaker makes developing and debugging Addins so much easier, there is still a huge documention gap in the MonoDevelop Addin system, but M. Hutch’s AddinMaker sure helps a ton (thanks mhutch!).