Daniel Vaughan

free range code

Obfuscating Multiple Xamarin.Android Projects with Dotfuscator

clock July 11, 2016 19:37 by author Daniel Vaughan

For a while I’ve been using Dotfuscator to obfuscate my Windows Phone and UWP apps. It's a great product and PreEmptive have excellent support. Recently I ported a large app to Xamarin Android. I was pleased that the obfuscation process was easy to integrate into the build process. There’s a good starter article here.

The steps laid out in the article work great if you’re only obfuscating the single assembly of your launchable Xamarin Android app project. If you have multiple projects then you may have a hiccup, as I did.

My app contains multiple projects. But, only two that I wished to be obfuscated. The first is the entry point assembly and the second, a referenced assembly with the bulk of my business logic.

The first indication that something was awry was when the linker was unable to bind to some missing methods in the second assembly. I first assumed this was due to me using InternalsVisible to expose some internal classes to the entry assembly. That wasn’t it.

When I went to verify that the assemblies in the APK were correctly obfuscated, I discovered that only the entry assembly had been obfuscated. The second assembly was unobfuscated (gah!). What I soon discovered, despite copying the second assembly back to the release directory, the unobfuscated assembly was making its way into the APK. As it turned out, the packaging process relies on any secondary assemblies being present in the following two locations:

  • <AndroidAppProject>\obj\<Obfuscated Build Configuration>\android\assets\
  • <AndroidAppProject>\obj\<Obfuscated Build Configuration>\linksrc\

It appears that either the Xamarin tooling copies assemblies prior to the AfterBuild MSBuild target, or that it draws the assemblies from the obj directory of the secondary projects. Please note that I am making use of Xamarin’s Ahead of Time compilation feature, which may have unduly thrown a spanner into the works.

You can resolve the wrong assembly issue by adding additional post-build copy statements in your Dotfuscator project; copying the secondary assemblies into those two directories listed above. That did the trick for me.

 



Automaticly Incrementing the Package.appxmanifest Version Number

clock August 28, 2015 01:01 by author Daniel Vaughan

When submitting a UWP or WinRT app to the Windows Store, you must increase the Version number of the package or the submission will fail. 

It can be a chore to manually update the version number. One solution is to use a pre-build event action that executes a Powershell script that increments the version number automatically. In this post you see how a Powershell script reads the Package.appmanifest file for your project, replaces the Version attribute, and overwrites the Package.appmanifest file; leaving your package ready to submit without having to modify the manifest file manually.

To get started, create a Powershell file in the root of your project. You can call it IncrementVersion.ps1. See Listing 1. The Powershell script expects the path to the working directory to be provided. When testing the script in the Windows PowerShell ISE, the working directory is set to the script root. When, however, the script is run via a Pre-build event, the working directory is supplied using a parameter.

As you may be aware, a package’s version number has four parts: major, minor, build, and revision. IncrementVersion.ps1 uses the same Major version that exists in the Package.appxmanifest file; it doesn’t change it. It does, however, overwrite the minor, build, and revision numbers. It calculates the new values using the current year as the minor part; the day of the year as the build part; and the minute of the day as the revision part. You can, of course, invent a different scheme for calculating the version number.

The script uses a multi-line regular expression to locate the Identity element in the Package.appxmanifest file. The content of the file is read using a Get-Content (gc) commandlet. The result of the Get-Content is an array, which is collapsed to a string using the -join command. A string is needed to allow the regular expression to search correctly across multiple lines. The regex object uses a callback to construct the new Identity element; replacing the version parts with the calculated values. Using a callback, rather than a simple call to -replace, provides more control over dynamically calculating the new version number parts.

Listing 1. IncrementVersion.ps1

param([string]$workingDirectory = $PSScriptRoot)
Write-Host 'Executing Powershell script IncrementVersion.ps1 with working directory set to: ' $workingDirectory
Set-Location $workingDirectory

$inputFileName = 'Package.appxmanifest'
$outputFileName = $PSScriptRoot + '/Package.appxmanifest';

$now = Get-Date
$versionMinor = $now.Year
$versionBuild = $now.DayOfYear
$versionRevision = ($now.Hour * 60) + $now.Minute

$content = (gc $inputFileName) -join "`r`n"

$callback = {
  param($match)
    [string]$versionMajor = $match.Groups[2].Value
    $match.Groups[1].Value + 'Version="' + $versionMajor + '.' + $versionMinor + '.' + $versionBuild + '.' + $versionRevision + '"'
}

$identityRegex = [regex]'(\<Identity[^\>]*)Version=\"([0-9])+\.([0-9]+)\.([0-9]+)\.([0-9]+)\.*\"'
$newContent = $identityRegex.Replace($content, $callback)

[io.file]::WriteAllText($outputFileName, $newContent)

To have Visual Studio execute this script whenever you build your app, you need to modify the project’s Build Events. Open your project’s properties by selecting the project node and hitting Alt+Enter. Add the following Pre-build event:

Powershell -File "$(ProjectDir)IncrementVersion.ps1" "$(ProjectDir)\"

Notice the trailing back slash? It's important because the $(ProjectDir) macro includes a trailing back slash, but it ends up escaping the quote, which breaks the script. Hence another slash is appended, which is escaped by the output of the macro. A fiddly little detail.

If you receive a message informing you that execution of scripts is disabled you may want to try modifying the execution policy by issuing the following command at a Powershell command line prompt with Admin privileges.

set-executionpolicy remotesigned

You may also choose to set the execution policy to unrestricted. Be warned, however, that there are security implications for allowing any script to execute on your computer.

That’s it. If all is in place, then your Package.appxmanifest file should update automatically, and you won’t need to manually change the version number each time you submit your app to the Windows Store.

Download the sample project: IncrementVersionNumber.zip (125.99 kb)



Order the Book

Ready to take your Windows Phone development skills to the next level? My book is the first comprehensive, start-to-finish developer's guide to Microsoft's Windows Phone 8. In it I teach through complete sample apps that illuminate each key concept with fully explained code and real-world context. Windows Phone 8 Unleashed

Bio

Daniel VaughanDaniel Vaughan is co-founder and president of Outcoder, a Swiss software and consulting company dedicated to creating best-of-breed user experiences and leading-edge back-end solutions, using the Microsoft stack of technologiesin particular UWP, WPF, and Azure. 

Daniel is a six-time Microsoft MVP, with experience across a wide range of industries including finance, e-commerce, and digital media. 
Daniel is the author of Windows Phone 8 Unleashed and Windows Phone 7.5 Unleashed, published by SAMS.

Daniel is a Silverlight and WPF Insider, a Microsoft Azure advisor, a member of the WPF Disciples, and a member of the Microsoft Developer Guidance Advisory Council.
Daniel also sits on the advisory board of PebbleAge, a Swiss Financial Software company.

While originally from Australia and the UK, Daniel is currently based in Zurich Switzerland. 

Daniel is the developer behind several acclaimed Windows Phone apps including Surfy Browser, Farlight, Intellicam and Splashbox; and is the creator of a number of popular open-source projects including the Calcium and Clog.

Daniel also manages the Windows Phone Experts group on LinkedIn; a group that has over 4500 independent developers, Microsoft employees, and Windows Phone enthusiasts.

Microsoft MVP logo Disciple
WPF and Silverlight Insiders

Groups

Windows Phone Experts Windows 10 Experts
LinkedIn Group

Sign in