Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic developer licence acquiring for Windows Store unit testing on a build server

For Windows Store applications, a developer licence is required to run the unit tests, which is fine for the individual developer on his personal machine.

But for a continuous integration process on a build server, we really need the ability to acquire the licence automatically.

Microsoft provides a command line tool, but it still creates a interactive window, which breaks the process.

TailoredDeploy.exe AcquireDeveloperLicense

So does anyone know of any other way to automatically acquire a developer licence? Spawning new build nodes is going to be hell if it needs manual setup via. VPN for each of them.

like image 906
Claus Jørgensen Avatar asked Nov 10 '12 12:11

Claus Jørgensen


1 Answers

I was suggested to use UI Automation, and here's what I've conjured up so far:

using System.Diagnostics;
using System.Threading;
using System.Windows.Automation;

class Program
{
    static void Main(string[] args)
    {
        var processStartInfo = new ProcessStartInfo(@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\TailoredDeploy.exe", "AcquireDeveloperLicense");

        var process = Process.Start(processStartInfo);
        process.WaitForInputIdle();

        Thread.Sleep(1000);

        var agreementWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children,
            new PropertyCondition(AutomationElement.ProcessIdProperty, process.Id));

        var iAgreeButton = agreementWindow.FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                          .FindAll(TreeScope.Children, Condition.TrueCondition)[2];

        var buttonPattern = iAgreeButton.GetCurrentPattern(AutomationPattern.LookupById(InvokePattern.Pattern.Id)) as InvokePattern;
        buttonPattern.Invoke();

        Thread.Sleep(10000);

        var processes = Process.GetProcessesByName("dllhost");

        var credentialsWindows = AutomationElement.RootElement.FindAll(TreeScope.Children,
            new PropertyCondition(AutomationElement.ProcessIdProperty, processes[0].Id));

        if (credentialsWindows[0].Current.Name == "Developer License")
        {
            var credentialsPane = credentialsWindows[0].FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                                       .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                                       .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                                       .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                                       .FindAll(TreeScope.Children, Condition.TrueCondition);

            var usernameTextBox = credentialsPane[3].GetCurrentPattern(AutomationPattern.LookupById(ValuePattern.Pattern.Id)) as ValuePattern;
            usernameTextBox.SetValue("[email protected]");

            var passwordTextBox = credentialsPane[5].GetCurrentPattern(AutomationPattern.LookupById(ValuePattern.Pattern.Id)) as ValuePattern;
            passwordTextBox.SetValue("password");

            var loginButton = credentialsPane[8].GetCurrentPattern(AutomationPattern.LookupById(InvokePattern.Pattern.Id)) as InvokePattern;
            loginButton.Invoke();

            Thread.Sleep(10000);

            var finishUpProcesses = Process.GetProcessesByName("TailoredDeploy");

            var finishWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children,
                new PropertyCondition(AutomationElement.ProcessIdProperty, finishUpProcesses[0].Id));

            var lastItems = finishWindow.FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                                        .FindAll(TreeScope.Children, Condition.TrueCondition);

            var closeButton = lastItems[3].GetCurrentPattern(AutomationPattern.LookupById(InvokePattern.Pattern.Id)) as InvokePattern;
            closeButton.Invoke();
        }
    }
}

To use this, a app.manifest is required to run in elevated mode:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
    </application>
  </compatibility>
</asmv1:assembly>
like image 169
Claus Jørgensen Avatar answered Oct 16 '22 09:10

Claus Jørgensen