Visual Studio 2015 Remote Debugging

When developing with expensive and unusual hardware in a team environment, debugging and testing can quickly become a chore; swapping devices with other developers and making concessions to complete individual components can quickly cripple a projects momentum, and may even lead to integration issues from oversights often made when a full set of hardware isn’t available to all developers for end-to-end debugging. Remote Debugging offers a clean solution to this, and Visual Studio 2015 makes this easy across multitude of different devices.

The application that I encountered that lead me on the quest to setting up a debugging environment was a work project involving a kiosk, which requires a number of external machines to be connected to it to accept and dispense money, print, and conduct cashless payments. I had heard of remote debugging previously, and had a few hesitations and questions:

  • Will it work without domain membership on all computers?
  • Does it use authentication?
  • Can I make it difficult to use the debugging machine for anything beyond debugging?
  • Is it simple to configure and maintain?

The end result was clean and simple to use, with minimal configuration. Note that all computers are using Windows 10, build 10586 or higher, and Visual Studio 2015 Update 1.

Development Hardware on Remote Debugging enabled computer.

Client Preparation

Firstly, the client should be prepared. This includes installing the debugging tools, securing the client machine, and configuring options to ease use and maintainability. I used this MSDN article (Set Up the Remote Tools on the Device) to get started.

  1. Install the Remote Debugging Tools, obtainable from Microsoft’s download site. You may need to restart afterwards.
  2. On the first run, you will need to configure some preferences. If you aren’t presented with the following window upon attempting to run the program, don’t worry – just enable a firewall exception on the nominated port which we will cover later.
  3. Set up a user account with a password if you don’t already have one, which can be used to access the file share which will hold the debugable application, and connect to the remote debugging tools.
  4. Set up a Windows share, with full permissions for the nominated user. VS2015-remote-debugging-08Remember to set full access in both the security and sharing pages. VS2015-remote-debugging-09I use hidden shares, as denoted by the ‘$’ following the share name. VS2015-remote-debugging-07
  5. Set a static IP address. In a domain environment, I prefer to achieve the same outcome via the DHCP server with a reservation instead. This isn’t strictly necessary, but simplifies things.
  6. Run the remote debugging utility from the start menu if it is not already running. VS2015-remote-debugging-03Permissions, authentication type, and port must now be set. Within the utility, click Tools, ‘Options’ to open the Options dialogue.VS2015-remote-debugging-04
  7. Set the default port of 4020, Windows Authentication, and add the desired user as the debug user in permissions.VS2015-remote-debugging-05
  8. Note the computer name if not a domain member, for remote authentication later.

Make Machine more Appliance-Like (Optional)

  1. Disable power saving, and update power preferences. I like to use the high-performance profile, set the power and sleep buttons to shutdown, disable sleep, and ensure the screen never turns off.
  2. Set up auto login. This can be done in accordance with this TechNet article about Setting up a kiosk.
    1. Open ‘RegEdit.exe’.
    2. Locate ‘HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon’.
    3. Set ‘AutoAdminLogon’ to ‘1’.
    4. Set ‘DefaultUserName’ to the desired username.
    5. Set ‘DefaultPassword’ to the desired password. Note that if either the username or password key is missing, you can simply add a string value at this location.
  3. Replace the shell with the debug client. This can be done in accordance with this superuser question (
    1. Open ‘RegEdit.exe’.
    2. Locate ‘HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon’.
    3. Set ‘Shell’ to the full path of the executable you wish to run. In my case, this was ‘C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe’.
    4. Restart. (Press Ctrl+Shift+Escape to bring up task manager if needed, when explorer isn’t running. From here you can start new tasks like ‘regedit’ or ‘explorer’).

Configure Solution

It’s now necessary to configure the solution to utilise this remote debugging agent. This can be done by modifying the local build configuration rather than making a new build configuration, but this will make it difficult to debug locally, and will prove to be more of a hindrance in a team environment.

  1. Connect to the windows share, and remember the credentials. You may need to connect to the \\COMPUTER and authenticating, before connecting to \\COMPUTER\MYSHARE$. If the remote debug machine is not a domain member, log in with COMPUTER\USERNAME.
  2. Open the solutions configuration manager. This can be found on the tool bar at the top of visual studio or in the solution properties.VS2015-remote-debugging-11
  3. Add a new Solution Configuration, and name it appropriately. You may wish to copy settings from your current profile. It’s likely that you will want to also create project configurations; tick the box.VS2015-remote-debugging-12
  4. Set the Active Solution Platform if desired, or adjust the project platforms against the profile.VS2015-remote-debugging-13
  5. Open the project properties for executable projects, and navigate to the ‘Build’ tab. Here you will need to ensure the ‘Configuration’ is set to the new one you have created, and set the output path to your share.VS2015-remote-debugging-14
  6. In the project properties, navigate to the ‘Debug’ tab and tick “Use remote machine”, and set the field to the IP address of the target computer.VS2015-remote-debugging-15
  7. Save All.

You should now be able to select the solution build configuration from the upper toolbar, and start debugging as usual. You may be re-prompted for authentication, log in as you would a windows file share, and remember credentials.


Adaptive Code via C#

Gary McLean Hall’s book ‘Adaptive Code via C#’ has been an invaluable reading experience. It has allowed me to transfer my shallow understanding of SOLID concepts that were filled with doubts and questions, to a comprehensive tool I can use on a daily basis to ensure my work is adaptable, and a pleasure to expand.


So what is SOLID anyway?

SOLID represents 5 principles that support writing code which can transform with ease to changing requirements, is extremely testable, and ensures teams can comprehend large repositories with ease.

S – Single Responsibility. SRP is pivotal in supporting ‘O’ and ‘L’. It mandates that every unit has one responsibility. I had difficulty in the past defining what this responsibility should be, but Hall’s examples and explanations tore away all the irrational perceived shortcomings that I had attached to this, and left a clear understanding of ‘how to cut the cake’. The worst part about this chapter (Chapter 5), was that it left me wanting to write code immediately, but at the same time hesitant because I hadn’t experienced the glory of the remaining ‘OLID’.

O – Open/Close principle. No matter how much I read about this, I felt I understood it, but somehow completely missed the point. It states simply that the code you write should be open to extension but closed to modification. This is further clarified in ‘L’. It’s almost like a contract; ‘always do this… never do that…’, to ensure dependency graphs aren’t broken in implementation.

L – The Liskov Substitution Principle. This was always a black duck for me, in that I never really bothered to invest the time in understanding it. It extends the foundation ‘O’ builds and explains how code may be extended, and how to compromise.

I – Interface Segregation. Interfaces are what make SOLID possible. No interfaces, no SOLID. This is a no-brainer with ‘SOL’ and ‘D’ in mind, but Hall uses this chapter constructively to further explain how these principles work together.

D – Dependency Injection. I had a warped understanding of Dependency Injection, poisoned by the many pointless implementations of Inversion of Control I had seen in my working life. Adaptive Code via C# set the record straight on this for me; it explains why dependency injection is one of THE most important aspects of modern OO development, and how it supports SOLID as a whole.

My favourite part of reading this book was its layout. It is separated in to 3 sections. The first covers the justification for SOLID, what modern software engineering encompasses, an overview of Unit Testing, and some simple design patterns. The second is strictly SOLID, and the third is a role play of an Agile team working through a project, and negotiating change as it arises. All 3 sections are a rewarding read, with lots to be gained in the subtle references alone.

An accessory to SOLID that I have consistently struggled with prior to reading was Unit Testing. I understood the point, and how to write a test, and implement it, but I had never seen any useful examples of real unit tests that provide real value. The examples expressed in Chapter 4, whilst shallow, set me on a path to bridge this gap, and I now can confidently and comfortably use unit testing to support my projects without hindrance.

Overall, the code examples are very simple to follow, and concise. If anything, they are too simple. The experienced programmer would likely look at them and understand the concept that is being displayed and discussed, however a lesser experienced programmer would probably identify all the techniques used, but may miss the underlying point of the particular arrangement in context.

The text generally read very well. I have had text books that have taken me hours to pass less than 5 pages. Adaptive code was very easy to get though more than 30 pages per hour however, and an IDE is not necessary. It was really relaxing to read. I would recommend it to all Java and C# developers interested architecture, and writing better applications, and the first section to non-programmers in the Software Engineering industry with an interest in quality software.