Pages

Thursday, August 18, 2016

Catching Up on Coding - TDD Part 1

I’ve been a software developer for twenty years, but am behind in some skills. This series chronicles my self-improvement.

There are some pretty high-tech tools out there, but nothing that matches the inspiration provided in the 70s TV show “Search” (originally “Probe”). I don’t have Burgess Meredith, a Probe Scanner or a catchy theme song to help me out, so, like Hugh O’Brian, I’ll have to rely on my wits and Test Driven Development (TDD).

Previously, on CUOC: The Syllabus.
Next Episode: TDD Part 2

 

Teaser

I’m not truly new to TDD. I wrote a (not very good) unit testing framework for Visual Basic 6 back in 2000. I’ve used TDD in professional projects. But now it’s time to make it a habit. To do that, I need a crash coarse, then retrofit my EduAgent code (applying “Test Eventually Development”) before writing new code.

Act 1 – The Elemental Education

Let’s give primary credit where it’s due. I read James Bender’s blog 30 Days of TDD. Bender’s series is very good overall. He does—frustratingly--have sloppy grammar and punctuation errors in every post. But his information is otherwise clear and solid. In fact, his description of SOLID is one of the best I’ve read. Thanks, James!

But first things first: what problem was TDD trying to solve?

Programmers, being human, don’t like to test our work. Most of us find it as hard as writers self-editing or composers checking for wrong notes. We like QA departments because they find our (careless) mistakes for us. We pretend to hate QA, because we pretend we’re egotistical Greek gods incapable of flaw.

Unit testing frameworks allowed testing the public interface of our classes. But that wasn’t enough. Kent Beck encouraged an upside-down approach to writing code, where we write a failing test first, then make it pass. This naturally builds up a library of tests that can be run quickly, reducing the chance of new features breaking the application, and building developer confidence. It also turned out that creating easily testable methods led to generally more maintainable code. Thus, some people revised TDD to mean test-driven design.

What are the elements of TDD? What’s needed to build testable code?

Elements

  • Test framework such as NUnit and xUnit.net
  • Test runner, for executing tests and viewing results.
  • Dependency Inversion (depend on abstractions) and Dependency Injection (decouple dependencies). Both are covered pretty well in this article.
  • Mocking (control results from external resources, such as databases)
  • Refactoring (improving code maintainability without changing the public interface)

Act 2 – Some Code, a Test

Here’s a simple example of TDD, creating code that needs to be tested, and problems with it. I’m using xUnit.Net because I’ve always liked it. I won’t go into how to set up your environment; you can learn that at Getting Started with xUnit.net. However, I do have three tips for using the VS Test Runner (which you open via Test > Windows > Test Explorer).

  • Tear off the Test Explorer into its own window, so that you can easily resize and see all the tests.
    image
  • Group the test results by class
    image
  • In your unit test project, add an app.config file with the following setting. This causes the result to display only the method name instead of the fully qualified name.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="xunit.methodDisplay" value="method"/>
      </appSettings>
    </configuration>
    

Our contrived application helps teachers grade coursework. We’re writing a class dealing with the coursework, and we’re consuming a third-party service—GradeMark—that returns a grade. One challenge, however, is we don’t control the grade that GradeMark returns given a set of scores. It depends on however the school has configured it. So, today 90% or higher could be an “A,” but tomorrow 93% or higher could be an “A.”

Our CourseWork class will have two methods. One that returns a percentage, and the other that returns a grade message. The grade in the message will come from the GradeMark “service,” and we’ll eventually have to mock that service.

First, in CourseWork, create a GetPercent function that doesn’t work. We want a failing test.

    public class CourseWork
    {
        public decimal GetPercent(decimal actual, decimal maximum)
        {
            throw new NotImplementedException();
        }
    }

In the unit tests project, create the test. Notice the naming convention I’m using along with nested classes; this will help make the test results readable. There are lots of naming conventions out there. Consistency and clarity are the big deals.

Our first test checks that we get back a percent in a particular format. We want “a hundred percent” to return as 100.00.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            [Fact]
            public void Return100PercentAs100PointZero()
            {
                var cw = new CourseWork();
                decimal percent = cw.GetPercent(100, 100);
                Assert.Equal(100m, percent);
            }
        }
    }

Run it and it fails.

image

Write enough code for the test to pass.

        public decimal GetPercent(decimal actual, decimal maximum)
        {
            decimal result = (actual / maximum) * 100m;
            return result;
        }

Run the test and it passes.

image

Our next test will check if the result is rounded. This does not depend on the first test; they could be run in reverse order.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var cw = new CourseWork();
                var percent = cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }
    }

Run it, and it fails.

image

Update the code to make it pass.

        public decimal GetPercent(decimal actual, decimal maximum)
        {
            decimal result = Math.Round((actual / maximum) * 100m,2);
            return result;
        }

image

That’s enough to demonstrate a basic test. Now, on to something that will require mocking.

Act 3 – Mocu-mental Grades

Let’s create a class that represents our fictional third-party service, GradeMark. Remember, it returns a grade when supplied a percent, but we can’t depend on what that grade will be. For our dummy service, we won’t even use the percent parameter.

    public class GradeMarkService
    {
        public string GetGrade(decimal percent)
        {
            var rnd = new Random();
            int code = rnd.Next(65, 70);
            return ((char)code).ToString();
        }
    }

We’re just returning a random letter A-D (no failures in our courses!). Back in our CourseWork class, we’ll start a function that returns a grade, and write a test for it that will fail. Here’s the test.

        public class CourseWork_GetGradeMessage_Should
        {
            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                var cw = new CourseWork();
                string msg = cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }

What we’re testing is getting the expected message text. We’re not testing if GetPercent works, and we’re not testing if the GradeMark service works. When we run the test, it fails, so we write this code to try to make it pass. Some people would say that we shouldn’t bother with the GradeMark service yet, but let’s assume we’re at that point.

        public string GetGradeMessage(decimal actual, decimal maximum)
        {
            var service = new GradeMarkService();
            return "The grade is " + service.GetGrade(GetPercent(actual, maximum));
        }

We got lucky; it failed. But, remember, we can’t guarantee what letter grade will be returned. It could have passed. Run the tests enough times and it will pass.

image

Our GetGradeMessage function has a dependency on the GradeMark service, and is tightly coupled to it. We need to loosely couple that dependency by injecting it. We could do that at the method level, like this:

        public string GetGradeMessage(decimal actual, decimal maximum, GradeMarkService gradeService)
        {
            return "The grade is " + gradeService.GetGrade(GetPercent(actual, maximum));
        }

But, typically, a service like this is consumed by the class. So, we’ll inject it in the class’s constructor.

    public class CourseWork
    {
        GradeMarkService _gradeService;

        public CourseWork(GradeMarkService gradeService)
        {
            _gradeService = gradeService;
        }

        public string GetGradeMessage(decimal actual, decimal maximum)
        {
            return "The grade is " + _gradeService.GetGrade(GetPercent(actual, maximum));
        }

Great, but that doesn’t really help us, does it? We still need a GradeMarkService to pass in during our test, and control the letter grade it returns. Using some mocking frameworks, it’s possible to mock a legacy object. But in this case, we’re hoping for one of two things from our vendor to make our lives easier.

An Interface

Ideally, our vendor has programmed to an interface, using the Dependency Inversion Principle. We’ll simulate that in our fictional service class.

    public interface IGrader
    {
        string GetGrade(decimal percent);
    }

    public class GradeMarkService: IGrader
    {
        public string GetGrade(decimal percent)
        {
            var rnd = new Random();
            int code = rnd.Next(65, 70);
            return ((char)code).ToString();
        }
    }

Next, we update our class to inject the interface we’re testing, instead of the concrete instance.

public class CourseWork
{ IGrader _gradeService; public CourseWork(IGrader gradeService) { _gradeService = gradeService; }

Our class is now ready for testing. We don’t need the GradeMarkService. We just need our own mock class implementing the required interface. Back in our test project, we’ll create that.

    public class GradeMarkServiceMock: IGrader
    {
        public string GetGrade(decimal percent)
        {
            return "B";
        }
    }

And, update our tests to accept the mock object.

            [Fact]
            public void Return100PercentAs100PointZero()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                decimal percent = cw.GetPercent(1, 1);
                Assert.Equal(100m, percent);
            }
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                var percent = cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }

        public class CourseWork_GetGradeMessage_Should
        {
            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                string msg = cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }

When we run our tests a few times, the GetGradeMessage test passes consistently.

An overridable class

Our vendor could also have made the GetGrade method overridable. In that case, we’d create a mock object, override GetGrade, and always return “B”. But with a significant object, there could be many problems doing that. It’s best if we can program against interfaces, because that way  we don’t have to use the original classes at all.

What’s a real-world example? What about a shipping service that our application uses to calculate shipping rates? Several problems could exist in consuming that service instead of mocking it:

  • It could be very slow to use that service in our tests.
  • It could return inconsistent results that affect our tests.
  • We might get charged every time we use the service.

Databases are another example. Testing against a database is difficult because you want the data to always start in a consistent state. Database tests are slow. They are better left for integration tests.

Refactoring

The last step in TDD is making the code better, and also making the tests better. For example, we get an instance of the CourseWork class repeatedly. We can declare that as a class field. xUnit creates a new instance of the class for each test, so it will will always be a new instance of CourseWork.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            public CourseWork _cw = new CourseWork(new GradeMarkServiceMock());

            [Fact]
            public void Return100PercentAs100PointZero()
            {
                decimal percent = _cw.GetPercent(1, 1);
                Assert.Equal(100m, percent);
            }
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var percent = _cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }

        public class CourseWork_GetGradeMessage_Should
        {
            public CourseWork _cw = new CourseWork(new GradeMarkServiceMock());

            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                string msg = _cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }
    }

Of course, rerun the tests and make sure they pass!

Tag

Test-driven development isn’t natural at first. But it’s got a rat-hits-food-lever pleasure I can’t deny. Kind of like having Probe Control’s Angel Tompkins whispering in my ear.

References

30 Days of TDD

Getting Started with xUnit.net

xUnit: display only method name

xUnit: Shared Context Between Tests

7 Popular Unit Test Naming Conventions

Naming standards for unit tests

An Absolute Beginner's Tutorial on Dependency Inversion Principle

Thursday, July 28, 2016

Writing to the Current User(s) Registry When Running as System

In a project I’m working on, I need to change the Group Policy Object (GPO) registry settings, both for the computer and for the logged in user. Both of these present problems. This article addresses the logged in user scenario.

The actual application is a Windows service running on the client that accepts requests from a remote machine. The complication is that the service will need to run as System so that it can write to any part of the registry.

Below is prototyping and troubleshooting using a Console application.

Goal

Run a Console application as the System user and write to the GPO that restricts running applications. Here’s the GPO if you want to look it up in Group Policy Editor (gpedit.msc).

User Configuration\Administrative Templates\System\Don't run specified Windows applications.

Challenges/Issues

64-bit Windows has both logical and physical registry entries. This is a problem when updating keys that are used by other programs (in this case, Windows itself). You have to be sure you’re updating the right key. The problem really presents itself when writing to the LOCAL_MACHINE hive. The physical location—such as the Wow6432Node key—depends on whether the application is 64 or 32 bits.

The CURRENT_USER hive doesn’t care about 64/32 bits. But remember that a computer can have multiple users logged on. Also, where does the System user’s settings go? Finally, how will we find out who is logged in? What a mess!

Tools and Environment

I’m running Visual Studio 2015 Community on 64-bit Windows 10.

This is the registry key/value we’ll be creating throughout, setting its value to 1.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun

Test Writing to the Registry

We first need to write to the registry and see the results. Create a Console Application with the following code.

using System;
using Microsoft.Win32;

namespace RegistryPrototyping
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WriteRegistry();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetBaseException().Message);
            }
            Console.WriteLine("Finished. Press any key to close.");
            Console.ReadLine();
        }

        static void WriteRegistry()
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }
    }
}

Run the application. You should get an error

Access to the registry key 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' is denied.

This is our first problem. Our code needs permissions to write to the registry.

For some developers, this problem will be hidden because they turn off UAC or always run Visual Studio as administrator. I don’t do either of these exactly because I’ll catch some permissions issue early.

The obvious next step is to close our app, open Visual Studio using Run as Administrator, then reopen/run the app.

image

No error, and the key is written to the expected registry key (i.e. the currently logged in user).

image

Great! Next task, testing as Local System.

But first, delete the DisallowRun key!

Testing as Local System

We need to run our app—either the .exe or Visual Studio—as Local System. I didn’t find a built-in Windows way to do this. The recommended method is to use Sysinternals’ psexec utility, which is normally used to execute commands on remote domain machines.

  1. Download psexec.
  2. Open a command prompt As Administrator (you must do this), and navigate to the folder where you extracted psexec.exe.
  3. Launch the desired application with the –i and –s switches. These run the application locally in interactive mode under the System account.

I right-clicked on my Visual Studio icon > Properties to get the path, and ended up with this command.

psexec –i –s “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"

When you launch this way, you’re running as if logged in under a different profile, so VS will go through its initial startup prompts.

  1. Open your Console solution; you’ll need to navigate to its location via C:\Users\[username].
  2. Run it. Check your registry key. Where the heck is the new value? Because we’re running as System, the registry value will be written to the .Default user key.

image

Well, heck! This obviously isn’t what we want. We need to write to the currently logged on user’s profile. But this result gives us a clue how we’ll solve our problem later.

Impersonation – False Start

At first, impersonation seems like the way to go. If I can just find out who’s currently logged on and working, I should be able to impersonate that user and write to the registry on that user’s behalf.

There are two problems with this.

  1. What if there are multiple users logged on? How do I find out which user is actively working?
  2. Will I need to run with elevated privileges? (hint: yes, of course)

If there are multiple users logged in, I didn’t find a way to determine who is actively using the computer. That seems like a poor requirement anyway. Don’t I care if, for instance, a scheduled task starts running as the logged in (but not active) user? Yes, because I might want my agent to prohibit it. What if it’s a headless system that’s always logged on? Worse, what if I want to run the client on a Windows server (which allows multiple simultaneous users via RDP)?

But maybe someone more clever than me wants to figure this out. There might be a way by looking at the active desktop(s).

The second problem is, for us, the impractical barrier to overcome. Writing to the registry requires elevation. The way we’d be impersonating the user would be to get a handle to a running process, then impersonating via that handle. But the user will not be running a known-elevated process. So, we’d be stuck. As soon as we tried to write to the registry, it would fail. And if we try to elevate the process (if we even could do that), the user would get prompted, defeating the goal of the program.

But we can still do what we want. After all, as System we can write to most parts of the physical registry.

Writing to the User’s Key

When we wrote to the System user’s logical hive CURRENT_USER, we ended up in the physical hive USERS. That’s where all the user registry settings are. CURRENT_USER is a symbolic link, a redirection for the active user. Here’s my computer’s USERS hive:

image

Those long SIDs are the users. If I can get those, I can write to the user’s Group Policy setting.

Step one, revise the WriteRegistry method.

static void WriteRegistry(string sid)
    {
        string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
        string valueName = "DisallowRun";
        string value = "1";
        keyName = keyName.Replace("HKEY_CURRENT_USER", @"HKEY_USERS\" + sid);
        RegistryValueKind dataType = RegistryValueKind.DWord;
        Registry.SetValue(keyName, valueName, value, dataType);
    }

Step two, crazy lots of code!

You’ll need these addtional references.

using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Diagnostics;
using System.Collections.Generic;

Use a Win32 API function to get the logged on users. This is some deeper stuff, and I didn’t write it. The most I did was put it in a class and make the function return all the users.

The meat of this—the cool part—is using Process.GetProcessesByName with an argument of “explorer”. This will return anyone logged on, because explorer is (typically) always running.

class WindowsIdentityHelper
{

    [DllImport("advapi32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern int OpenProcessToken(
    System.IntPtr ProcessHandle, // handle to process
    int DesiredAccess, // desired access to process
    ref IntPtr TokenHandle // handle to open access token
    );

    [DllImport("kernel32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern bool CloseHandle(IntPtr handle);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
    int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

    public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_IMPERSONATE = 0x0004;
    public const int TOKEN_QUERY = 0x0008;
    public const int TOKEN_QUERY_SOURCE = 0x0010;
    public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    public const int TOKEN_ADJUST_GROUPS = 0x0040;
    public const int TOKEN_ADJUST_DEFAULT = 0x0080;
    public const int TOKEN_ADJUST_SESSIONID = 0x0100;
    public const int TOKEN_READ = 0x00020000 | TOKEN_QUERY;
    public const int TOKEN_WRITE = 0x00020000 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT;
    public const int TOKEN_EXECUTE = 0x00020000;

    public static List GetLoggedOnUsers()
    {
        List users = new List();
        string errs = "";
        IntPtr hToken = IntPtr.Zero;
        //Get a process that will always be available.
        foreach (Process proc in Process.GetProcessesByName("explorer"))
        {
            try
            {
                if (OpenProcessToken(proc.Handle,
                TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
                ref hToken) != 0)
                {
                    WindowsIdentity newId = new WindowsIdentity(hToken);
                    CloseHandle(hToken);
                    users.Add(newId);
                }
                else
                {
                    errs += String.Format("OpenProcess Failed {0}, privilege not held\r\n", Marshal.GetLastWin32Error());
                }

            }
            catch (Exception ex)
            {
                errs += String.Format("OpenProcess Failed {0}\r\n", ex.Message);
            }
        }
        if (errs.Length > 0) { throw new Exception(errs); }
        return users;
    }

And a method to write to the users’ registries.

static void WriteToLoggedOnUsers()
{
    foreach (var user in WindowsIdentityHelper.GetLoggedOnUsers())
    {
        try
        {
            WriteRegistry(user.Owner.Value);
            Console.WriteLine("Updated user " + user.Name + "  SID " + user.Owner.Value);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetBaseException().Message);
        }
    }
}

 

Notice we’re using WindowsIdentity.Owner.Value to return the SID. The property .Owner.AccountDomainSid doesn’t return the full, correct SID.

Finally, change the Main method.

static void Main(string[] args)
{
    try
    {
        WriteToLoggedOnUsers();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetBaseException().Message);
    }
    Console.WriteLine("Finished. Press any key to close.");
    Console.ReadLine();
}

One last thing before running the app. If you really want to test it, create a local user (named Test would be good), log that user on, leave it running and switch back to your regular user.

Now, run the application.

image

Check those User SIDs!

image

image

And finally, to prove the redirection, we’ll look at our CURRENT_USER hive.

image

(Remember, now, to delete those keys. You might also log off and delete the test user.)

Wrap Up

Our goal was to write to the logged on users’ Group Policy keys, with the future intention of preventing them from running certain applications. We need to do this running as System, and found that impersonation wouldn’t work because we had use an elevated process. Instead, we wrote to the running users’ physical registry keys.

One interesting aspect of this session is that there’s not a certain automated way to test for correctness. If I wrote a test that looked at a logical key (like CURRENT_USERS\…), and then checked if the value existed, I wouldn’t know if the correct physical key was updated. This may be a time when a human needs to test. (Maybe there’s a clever way around this, though.)

Full source code can be found after the References.

References

Registry Redirector

Registry Keys Affected by WOW64

Group Policy Object – Disallow Run

WindowsIdentity.Impersonate

Using OpenProcessToken  <=this is where the Win32 code came from. Very useful.

OpenProcessToken function

OpenProcessToken Access Rights

Constants for Token Access Rights

Process.GetProcessesByName

My machine’s named Nesbit, after the great children’s fantasy author.

Full Source

using System;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Diagnostics;
using System.Collections.Generic;

namespace RegistryPrototyping
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WriteToLoggedOnUsers();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetBaseException().Message);
            }
            Console.WriteLine("Finished. Press any key to close.");
            Console.ReadLine();
        }

        static void WriteRegistry(string sid)
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            keyName = keyName.Replace("HKEY_CURRENT_USER", @"HKEY_USERS\" + sid);
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }

        static void WriteRegistry()
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }

        static void WriteToLoggedOnUsers()
        {
            foreach (var user in WindowsIdentityHelper.GetLoggedOnUsers())
            {
                try
                {
                    WriteRegistry(user.Owner.Value);
                    Console.WriteLine("Updated user " + user.Name + "  SID " + user.Owner.Value);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.GetBaseException().Message);
                }
            }
        }
    }
}


class WindowsIdentityHelper
{

    [DllImport("advapi32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern int OpenProcessToken(
    System.IntPtr ProcessHandle, // handle to process
    int DesiredAccess, // desired access to process
    ref IntPtr TokenHandle // handle to open access token
    );

    [DllImport("kernel32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern bool CloseHandle(IntPtr handle);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
    int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

    public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_IMPERSONATE = 0x0004;
    public const int TOKEN_QUERY = 0x0008;
    public const int TOKEN_QUERY_SOURCE = 0x0010;
    public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    public const int TOKEN_ADJUST_GROUPS = 0x0040;
    public const int TOKEN_ADJUST_DEFAULT = 0x0080;
    public const int TOKEN_ADJUST_SESSIONID = 0x0100;
    public const int TOKEN_READ = 0x00020000 | TOKEN_QUERY;
    public const int TOKEN_WRITE = 0x00020000 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT;
    public const int TOKEN_EXECUTE = 0x00020000;

    public static List GetLoggedOnUsers()
    {
        List users = new List();
        string errs = "";
        IntPtr hToken = IntPtr.Zero;
        //Get a process that will always be available.
        foreach (Process proc in Process.GetProcessesByName("explorer"))
        {
            try
            {
                if (OpenProcessToken(proc.Handle,
                TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
                ref hToken) != 0)
                {
                    WindowsIdentity newId = new WindowsIdentity(hToken); 
                    CloseHandle(hToken);
                    users.Add(newId);
                }
                else
                {
                    errs += String.Format("OpenProcess Failed {0}, privilege not held\r\n", Marshal.GetLastWin32Error());
                }

            }
            catch (Exception ex)
            {
                errs += String.Format("OpenProcess Failed {0}\r\n", ex.Message);
            }
        }
        if (errs.Length > 0) { throw new Exception(errs); }
        return users;
    }

}

Friday, July 22, 2016

Catching Up on Coding - The Syllabus



I’ve been a software developer for twenty years, but am behind in some skills. So, like Dack Rambo in the 70s TV show “Sword of Justice,” I’m taking myself to school. Just without the prison. Or the awesome hair.

Next Episode: TDD Part 1

 




Teaser

“The deal of the cards begins the game.”

Act 1 – The Project

I’ve already started a hobby project named EduAgent. The purpose of EduAgent is:
Allow a user to block and allow applications on remote Windows computers.
The application’s architecture is simple enough:
  • An agent, which is a Windows service running on client computers.
  • A web application that has bidirectional communication with agents.
  • A shared library.
  • A database.
That should be enough complexity for me to apply each area I want to improve in.

Act 2 – The Skills

I’ve done some work in most of these. However, it’s been awhile, and every job listing seems to ask for them (regardless of what’s actually in use).
  • TDD (xUnit)
  • SOLID
  • DDD
  • Design Patterns (major)
  • Git
  • Dependency Injection
  • REST/WebAPI
  • MVVM (Angular/Typescript)
  • CSS Preprocessing (SASS)
  • Azure (maybe)
  • Security
  • Scalability (maybe)

Act 3 – The Rules

Each post will be on a subject, and will include:
  1. How much I (think) I know about the subject
  2. The problem to solve
  3. Before and after code samples
  4. Lessons Learned
  5. References

Tag

How much will my experience help me? I’m betting, a lot. After all, I’ve got all those old TV show heroes to help me out.
“The spade is the sword of justice. Its rapier marks the end.”
image
“The spade is the sword of justice. Its rapier marks the end.”

Wednesday, July 13, 2016

Quickly Enable Mercurial Keyring for BitBucket

These instructions will work generally for pushing to any remote URL, but the example is specifically for BitBucket. The steps specifically require TortoiseHg, which includes Mercurial Keyring. If not using Tortoise, you would need to install Keyring yourself.

Mercurial Keyring

Instructions

Open Tortoise Hg Workbench, Open File > Settings > Global (or repository) Settings > Extensions

Check mercurial_keyring

image

Click OK,  Close and restart Workbench as directed.

image

Open File > Settings > Repository Settings. Click Edit File

image

In the repository’s .hg\hgrc file, add the following setting. Including the username at the start of the URL eliminates the need for an “admin” setting. Note that the password is not stored here.

# Generated by TortoiseHg settings dialog
[paths]
BitBucket=https://bladewolf55@bitbucket.org/bladewolf55/eduagent

Save, close Workbench and reopen.

Push the repository. You’ll be prompted for the password. After a successful push, you won’t be prompted again for the password. It has been locally stored encrypted.

Wednesday, June 15, 2016

Create an Easily Debuggable Windows Service

In a previous job, I needed to create Windows services. One thing that had tripped me up in the past was being able to debug the service. I figured someone (or ones) had solved this, so I did a bunch of research, consolidated what I found, documented it, and am finally (three years later?) posting it.

With the setup, below, you’ll have a Windows service that:

  • Runs in debug mode as you’d expect, without having to set unnecessary breakpoints.
  • Can run as a console app, allowing you to simply double-click the exe. This is useful for many things:
    • Output running messages to the console (the same info you’re logging, most likely).
    • Perform one-off runs for things like integration services that run on a schedule.
    • Easily run elsewhere without having to install as a service.

In addition, my steps include Nice-to-Dos like file and service naming, startup type, etc. These are more for me than you, so that I don’t have to look them up again, so think of them as a bonus.

The example below creates a sample FileImport service. Note that Visual Studio Express doesn’t have a Service project, but you can still create a service. (Sadly, I’m not covering that here, but might do so in a future post.)

Create a new Windows Service project.

image

Change the Assembly output type to Console Application (for debugging).  This, in my opinion, is the big deal. I can now write my program just like I would a console application, which is how I want to think of a service.

This is also a good time to change the assembly information (title, company, etc.).

image

Select Servic1.cs. Rename the Service1.cs file/class name, e.g. to FileImport.cs.

imageimage

image

Select FileImport.cs and view the designer (Shift F7), change ServiceName, e.g. FileImport

image

Rick-click design surface and choose Add Installer

image

Open ProjectInstaller.cs designer, select ServiceInstaller1 and edit:

image

  • Description
  • DisplayName, e.g. “Sample File Import”
  • ServiceName. Should be correct from Service1 designer change, otherwise FileImport
  • StartType, e.g. Automatic

image

If desired, in ProjectInstaller designer, select ServiceProcessInstaller and edit

  • Account = User (set to NetworkService or LocalService if desired.)

image

image

Open FileImport.cs code view, create a public member Start() for debugging.

namespace FileImport
{
    public partial class FileImport : ServiceBase
    {
        public FileImport()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }

        public void Start(string[] args)
        {
            OnStart(args);
        }

    }
}

Change Program.Main() to this (or similar).

namespace FileImport
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new FileImport()
            };
            // If you don’t want the exe to run as console when double-clicked, then use:
            //   if (System.Diagnostics.Debugger.IsAttached)
            if (Environment.UserInteractive)
            {
                Console.WriteLine("Service running, press  to stop.");
                ((FileImport)ServicesToRun[0]).Start(null);
                Console.ReadLine();
                ((FileImport)ServicesToRun[0]).Stop();
            }
            else
            {
                ServiceBase.Run(ServicesToRun);
            }
        }
    }
}

At this point, you can run the project. It will open a console window and wait.

image

If you install the service, when the service is started it behaves like any other service, i.e. doesn’t display the console window.

Our service isn’t doing anything, so let’s see what the benefit is to creating a service as a console app instead of the default Windows app. We’re not going to do anything fancy like multithreading, I just want to give a flavor. In FileImport.cs, use the following code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace FileImport
{
    public partial class FileImport : ServiceBase
    {
        Timer _timer = new Timer(5000);

        public FileImport()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            _timer.Elapsed += OnTimerElapsed;
            _timer.Start();
        }

        private void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("The time is--or, to be precise, was: " + DateTime.Now.ToString());
        }

        protected override void OnStop()
        {
            Console.WriteLine("Stopping. Here's one method where you'd handle processes that shouldn't be interrupted, gracefully stop them, then end the service. Press  to finish stopping.");
            _timer.Stop();
            _timer.Dispose();
            //etc.
            Console.ReadLine();
        }

        public void Start(string[] args)
        {
            OnStart(args);
        }

    }
}

Run the program and it will output something like this.

image

Now, if you were to install and run this as a service, you still wouldn’t see anything. But you can imagine adding appending text to a file (for example) in the OnTimerElapsed event.

        private void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            string msg = "The time is--or, to be precise, was: " + DateTime.Now.ToString() + "\r\n";
            System.IO.File.AppendAllText(Environment.ExpandEnvironmentVariables("%USERPROFILE%\\TestFileImport.txt"),msg);
            Console.WriteLine(msg);
        }

Of course, I can drop into the debugger as expected.

image

There you go! A simple way to build better Windows services.

References

http://einaregilsson.com/run-windows-service-as-a-console-program/

Friday, June 3, 2016

(Underrated) Work Skills

I’m not sure what “underrated” means. Or even whether these are truly “skills.” But, this article was interesting, so I synthesized and summarized what the (supposed) CEOs were looking for.

10 CEOs Answer The Question, What Are The Most Underrated Skills Most Employees Lack?

The one “skill” I take exception to was related to email. The CEO argued that a person should be able to find an email--without searching—in under thirty seconds. While I think it’s good and valuable to keep a clean inbox, I think it’s dumb to shortchange searching like that. By searching, I can find an email I need in under five seconds. Isn’t that a better use of my time?

My area for improvement: Organize and lead a team.

  1. Be succinct
  2. Be reliable (manage tasks/deliverables without reminders).
  3. Use elegant humor
  4. Write well
  5. Reduce chatter (inbox zero)
  6. Use lists effectively
  7. Golden Skill Triangle:
    • Figure out what to do (next)
    • Write effective goals (with due dates).
    • Organize and lead a team to execute large scale plans.
  8. Own the job

Sunday, May 22, 2016

VB.Net Windows Project to C# Conversion Tools Quick Review

If you’re looking for a thorough comparative review, this isn’t it! But, here are a few tools I looked at for converting a complex VB.NET project to C#.

Convert.NET by fish’s dotNET

  • Cannot be used commercially with buying the (reasonably priced) license.
  • Stand-alone, but can be added as Tool.
  • Other features besides converting.
  • Conversion of project had the most problems of any tool.

SharpDevelop

  • Only 4.4 can convert from VB to C#. Feature does not exist in version 5.
  • Project isn’t very active, because free versions of Visual Studio are much more readily available.
  • Conversion fidelity will work better with .NET 4.5 or older.
  • Better conversion that Convert.NET
  • Free for commercial use.

VBConversions

Instant C#

  • Commercial tool, expensive $159. (But worth it for a paid contract.)
  • Claims near-perfect fidelity.
  • Has free edition for smaller projects, 2000 line project conversion limit.

My choice: VBConversions, because of the better post conversion tools that show where errors are. However, one thing Instant C# did that I like is automatically generate a variable copy when a VB.NET for…each manipulated the iterating variable.

foreach (string field in fields)
{
   string fieldCopy = field;
   fieldCopy = fieldCopy.Trim();
   ...
}

VBConversions marked it with an error, essentially leaving the code with a bug. If I weren’t to check the errors, this could be a problem because the code would still compile.

foreach (string field in fields)
{
   // field = field.Trim(); VBConversions Warning: A foreach variable can't be assigned to in C#.
   string fieldType = "";
   ...
}

In both cases, it would be wise to set up Visual Studio to treat their comments as Tasks, assuming they consistently start with “VBConversions” or  “INSTANT C#”. Then, go through each comment and remove it after evaluation.

Regardless of the tool, professional diligence says to review every error/message the conversion reports.

References

Get rid of the ‘Missing XML comment for publicly visible type or member’ warning