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.

VS2015-remote-debugging-01
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.
    VS2015-remote-debugging-02
  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 (http://superuser.com/questions/435275/can-you-disable-windows-explorer-from-starting-with-windows).
    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.

VS2015-remote-debugging-16

Cash Payment with MEI and C# – Part 1

Although getting off to a shaky start with an MEI bill/note recycler, after some consultation with the supplier, firmware upgrades, and software reprovisioning, development has become a really nice experience in contrast to other hardware I have encountered. The MEI SCR 8327 is a note accepter and recycler; it will accept note/bill payment and can also dispense notes back to customers. A recycler differs from an accepter and dispenser because it can accept a note into its dispensable pool, which this unit stores on a drum internally.

cash-payment-with-mei-and-c-pt1-05

I struggled to get the device to function at first. I explored the MEI websites, downloaded everything that looked relevant, and attempted to install drivers and samples. MEI hardware seems to be of high build quality. The device exhibits nice fabrication, high serviceability and modularity, and is proudly represented at almost every kiosk I have encountered in my life, however their organisation of critical documents online is somewhat poor. My problems started when I attempted to connect it to my development PC (I develop on Windows 10, 64bit, with .Net 4.6), and try out the sample applications. I first attempted with the serial port, accessible through a tail at the rear. This resulted in no response. I then tried to install the USB drivers and connect the unit to my computer. The drivers installed without issue, but the device was in a Code 10 state and wouldn’t start.

After becoming stuck at this point I contacted the supplier who eventually connected me to a representative from Crane Payment Innovations (the MEI parent company). The representative (Glenn) was immensely helpful, and after 5 minutes of email conversations we had a Team Viewer session established and began making progress. The software I had downloaded was actually no longer relevant, the drivers were no longer supported, and the software and drivers I was issued are still not available on their website.

He first connected to the device with an application called “Cashflow STS v7.12”, using a new driver which was digitally signed and functional to connect via the device’s USB port (which is obnoxiously presented on the front of the device). From here he was able to upgrade the devices firmware, and enable the Serial port. The device was stuck in a ‘Stand Alone’ state form the supplier, and the serial port was not responsive nor usable. After moving out of this state, and setting up the note values and profiles to accept, he demonstrated their API through the example program, “CPI Integration Toolkit”.

The application seemed to separate out all the basic functions I would imagine that anyone would expect the platform to provide. You can:

  • Accept notes.
  • Decide what to do with an inserted note.
  • Empty the recycler to the cash box.
  • Return a note from the recycler.
  • Get the status of the hardware.
  • Perform simple configuration.

cash-payment-with-mei-and-c-pt1-03

The workflow of the primary use-case of this device seems pretty straight forward. You put the device in a listening state, which in turn allows a note to be inserted. Once the note is inserted the machine tries to match it to a configured denomination profile. If a match is found it is held in escrow. Escrow is like a buffering system for inserted notes; other models support multi-note escrow, allowing the ‘session’ of inserted notes to be returned to the customer who inserted them which might be desirable if the transaction was cancelled. This particular unit only holds a single note in an escrow state, and it must be either recycled or sent to the cassette, if not manually rejected. The recycler of this specific unit can hold 2 different denominations, and is configurable, with a total capacity of 60 notes (according to the sample application). Once the note is actioned, the device leaves the escrow state and returns to an idle state. The hosting system could then choose to raise some event or perform an action knowing that a note has been received, or the device could simply be told to go back into an accepting state.

cash-payment-with-mei-and-c-pt1-02

Viewing the demo application’s code initially made my hair jump after seeing ReSharper litter the main scrollbar (with the most orange markers I have ever seen) , and observing that all the code driving the demo was stored crudely in the code behind. Despite this, the code was actually nicely laid out, and lent itself well to learning, with well though-out comments, validation, and guidance distributed throughout the methods.

As described above, the machine should first enter an accepting state, this is done by calling the EnableAcceptance method on the device instance.

try
{
// Ensure communications are open
if (!_scr.IsOpen)
{
// Cannot enable acceptance. Communications are not open.
return;
}
// Enable acceptance
_scr.EnableAcceptance();
}
catch
{
// Communications are not open, or unknown/unexpected exception.
}

When a note is inserted, it will fire the event bound to the DocumentStatusReported event. This would allow an implementing system to check that the document is in a state where it can be stacked, and then proceed to stack the note to the recycler or cassette. The system could even decide to return the note.

To stack the note to the recycler:

try
{
// Ensure we are at a point where stacking is allowed.
if (_scr.DeviceState != DeviceState.ESCROWED)
{
           // Cannot Stack to Recycler : Device state != Escrowed
return;
}
// Check to see if this document is enabled for recycling.
var bCanStackToRecycler = false; // Default to False until we are sure we can recycler this document.
// Make sure we are dealing with a Banknote object
if (_document != null && _document is Banknote)
{
// Get a reference as a Banknote
var banknoteTmp = _document as Banknote;
var recyclerNoteTable = _scr.GetRecyclerNoteTable();
// Loop through the table and compare the 'ISO' and the 'Value'
foreach (var entry in recyclerNoteTable)
{
if (entry.ISO == banknoteTmp.ISO && entry.Value == banknoteTmp.Value)
{
// Valid entry- check the 'IsRecyclingEnabled' property
if (entry.IsRecyclingEnabled)
{
bCanStackToRecycler = true;
}
break;
}
}
}
// Abort if we cannot stack this document to the recycler
if (!bCanStackToRecycler)
{
// Cannot Stack to Recycler. Document is not enabled for recycling.
return;
}
// Stack the document to the recycler.
_scr.StackDocumentToRecycler();
}
catch
{
// See documentation for the plethora of issues that could arise.
}

To stack the note to the cassette:

try
{
// Ensure we are at a point where stacking is allowed
if (_scr.DeviceState != DeviceState.ESCROWED)
{
// Cannot Stack to Cassette : Device state != Escrowed
return;
}
// Stack the document to the cassette.
_scr.StackDocumentToCassette();
}
catch
{
// See documentation for the plethora of issues that could arise.
}

To return the note:

try
{
// Ensure we are at a point where stacking is allowed
if (_scr.DeviceState != DeviceState.ESCROWED)
{
// Cannot Return the Document : Device state != Escrowed
return;
}
// Return the document
_scr.ReturnDocument();
}
catch
{
// See documentation for the plethora of issues that could arise.
}

You could now re-enable the device to continue accepting notes. If nothing was to be inserted for a long time, it might be desirable to disable acceptance.

try
{
// Ensure communication is open
if (!_scr.IsOpen)
{
// Cannot disable acceptance. Communications are not open.
return;
}
// Disable acceptance
_scr.DisableAcceptance();
}
catch
{
// communications are not open, or unknown/unexpected exceptions.
}

You could issue change to your customer by dispensing notes like so:

// Set the index and quantity to dispense from the recycler accordingly.
int iIndex = 1;
int iCount = 2;
try
{
// Ensure we are in a state where we can dispense documents.
switch (_scr.DeviceState)
{
case DeviceState.IDLE:
// Ensure we aren't currently accepting.
_scr.DisableAcceptance();
break;
case DeviceState.HOST_DISABLED:
// Ok to proceed.
break;
default:
// Cannot Dispense Documents : Device state == _scr.DeviceState
return;
}
// Input has been validated so dispense the document(s)
_scr.DispenseByCount(iIndex, iCount);
}
catch
{
// Device is not in a valid state, index is invalid, quantity is invalid, comms loss, or other unknown error.
}

Decisions can be made on how to route notes and perform transactions by using the recycler note table. calling the GetRecyclerNoteTable command on the device instance will return an object describing the state of the devices reserves. The cassette should be manually monitored however.

I will follow up this article once I have completed the integration of this device into my own project, and outline any more issues that arise. Despite the obvious limitations that present themselves with the limited core instruction set, the hardware seems well fabricated, the API is easy to follow, and the features sensible to standard applications. I look forward to exploring other MEI/CPI devices in the future.

Sandcastle Help File Builder and VS2015

I have been working on a diverse set of projects this year, primarily based around .Net, and the need for documentation consistently arises. Some projects require user manuals, others API specifications, and some would simply benefit from a list of endpoints or settings delivered in a format accessible to integrators and testers. With limited research, I found SHFB (Sandcastle Help File Builder) and many other competing products in this space. This guide is primarily focused on helping you hit the ground running with Sandcastle Help File Builder and your .Net projects in Visual Studio 2015, and is in no way a definitive guide. I will update and extend this post as time permits.

Choices

As previously mentioned, there are a plethora of competing products aimed at extracting beautiful and usable documentation from your .Net solutions. If you decide by the end of this article that SHFB isn’t for you, you may wish to check out some of the following alternatives I initially considered.

Doxygen

http://www.doxygen.org/

Doxygen was one of the first free products I encountered, and it looked to be well established, with a primary focus on C++. It boasts a number of large projects using it from KDE to FLAC, and is seemingly very community driven. Although the project does support .Net (and C# specifically) I was concerned that I would need to put too much effort into using an maintaining it alongside my target solutions, and all the example documentation I viewed I found visually repulsive – although I am sure this wouldn’t require much effort to correct. I may revisit this for future C/C++ projects.

NDoc

http://ndoc.sourceforge.net/

NDoc seemed like a capable tool intended for use with .Net projects. Although free, it shows significant signs of age, and I am skeptical of its capabilities in contrast to the competition. To use it you set up an additional build step in your project/solution, which will take the XML documentation output from your target, and work through its own build process on this file. This seems like a fairly standard approach, but I have higher expectations.

Docu

http://docu.jagregory.com/

Docu was probably my favourite of all the documentation generator/formatters that I inspected. Free, like all mentioned in this article, Docu is primarily concerned with looking great, and simplicity. James (the project author) seems to have done an excellent job, and put a lot of effort making something awesome. My only turn-aways from this, was that its IDE and build integration is minimal – although this isn’t *really* a problem, and its output capability is limited to webpage output at present. I would like to produce well formatted PDFs longer term – although I may investigate bridging the development gap in doing so with this project in future. What I particularly like about this project is how sincere and clear James is in communicating the projects intended audience and capabilities. No bull-shit, and straight to the point.

Sandcastle Help File Builder

https://github.com/EWSoftware/SHFB

Sandcastle Navigated Example

Sandcastle is my final choice (as is now pretty obvious) with which to proceed in learning about and integrating with my projects. The Visual Studio integration  makes it easy to keep track of, customise, and further extend documentation with your solution, custom project types enable you to enhance your Sandcastle project with custom components, and the available output types are diverse, from webpages to docx and chm. This all comes at the expense of a clumsy and unrefined experience, however the learning curve is seemingly less than I initially believed, and it is overall a nice product to use. My only complaint with substance from using this product is how slow it is to build.

Getting Installed

The installation of SHFB is reasonably straight forward, however there are a couple of sneaky and less-impressive aspects to watch out for. Firstly, the installation process is irritating. It isn’t hard, and it does work, but the delivery is non-standard, and bothersome. Secondly, a restart is required to avoid nondescript errors when beginning projects and building content, which in this day and age I feel is inexcusable considering the subject is a meager development accessory. It is free though, and pretty impressive otherwise – so let’s be nice :).

  1. Head to the GitHub site and download the latest version. https://github.com/EWSoftware/SHFB/releases
  2. Extract the ZIP archive.
  3. Run SandcastleInstaller.exe and click through the installer.
  4. Restart

Note that on each page, there may be an install button in the primary content area for each component; be sure to be on the lookout. It is easy to get click-happy and miss them. Also note that the restart after completion is necessary, presumably because of how the installer relies on molesting environment variables.

Project Preparation

Preparing your project is pretty easy. You simply need to add comments in the .Net documentation style, and enable XML documentation output.

Firstly, enable documentation output.

  1. Open your project properties.
  2. Select the ‘Build’ tab.
  3. Under the ‘Output’ heading, select ‘XML documentation file: …’
  4. Save properties and rebuild.

Target Project Properties

Documenting your code is easy! Simply enter ‘///’ on the line above any aspect you would like to capture in your documentation and fill in the body of the auto-generated comment block.

Example Code Comment for XML Doc

If you use ReSharper, you may wish to update your preferences to automatically copy XMLdoc comments when you implement an interface or extend something. This is a great time saver, and worth integrating into your workflow.

  1. Open ReSharper’s options in your desired context.
  2. Expand the ‘Code Editing’ sub-tree.
  3. Select the ‘Member Generation’ node.
  4. Select ‘Copy XML documentation from overridden members’ option.
  5. Save.

Resharper Options

Sandcastle

When you go to add a new project to your solution for sandcastle, you will likely encounter a confusing division of options. If you were to look under ‘Documentation’ projects in the ‘Visual C#’ category, you would stumble upon the options below.

Sandcastle CS Projects

Instead, add a new project, and explore the parent ‘Documentation’ category to see a singular Sandcastle option as below. Create a new ‘Sandcastle Help File Builder Project’, and this step is complete.

Documentation Projects

If you are faced with an error whilst attempting to add this project (Something about ‘Documentation1’?), it is most likely due to not restarting your computer after installing Sandcastle.

Configuring Your Sandcastle

With your solution boasting both a documentation project, and a documentable project, you are ready to progress. Next, add a documentation source to your Sandcastle project.

  1. Expand your Sandcastle project in the solution explorer.
  2. Right-click the ‘Documentation Sources’ node.
  3. Select ‘Add Documentation Source’
  4. Browse and select the *.*proj file applicable.
  5. Press Open.
  6. Build your project.

Once this is complete, it is necessary to manually add documentation for Namespaces if desired, or disable namespace documentation. To do the former, manually add namespace documentation:

  1. Open the project properties (for the documentation project).
  2. Navigate to the ‘Summaries’ tab.
  3. Click the ‘Edit Namespace Summaries’ button.
  4. Select the namespace for which a description is to be added, and type it in the bow below.
  5. Once complete click close.
  6. Save the project properties.

Sandcastle Namespace Summaries

Once the Namespace summaries dialogue is present, it is possible to disable summary text for a namespace by deselecting it.

On the ‘Build’ tab of the documentation project’s properties, it is possible to enable more types of output. OpenXML and Markdown don’t appear to be supported out of the box, and will likely yield a build error.

Sandcastle Build Options

he ‘ContentLayout’ file makes it possible to change page properties and manage static content. It would be advisable at this point to attempt to build your project and check out the output. This can be found in the ‘Help’ subdirectory of the project folder. Note that it may take a while to complete a build, despite Visual Studio prematurely claiming success.

Sandcastle Example CHM File

The CHM output (above) despite the ugliness of its host, appears to be marginally more usable than the html output below. My very limited research suggests the necessity of server side components to support search functionality. I assumed it was handled client-side, but haven’t investigated further.

Sandcastle HTML example

Conclusion

Sandcastle, although not perfect, makes it easy to create attractive and complete documentation from your source code comments, and consequently eases the burden of managing documentation. API documentation can now be minimally managed by a team member with minimal coding experience, and access the project, and easily incorporated into build processes for inclusion with releases.

I would like to explore docx/pdf output in the future, and rectifying or removing the search from the HTML output. I also observed that the side menu in the HTML output would hide components as I navigated into my tree of namespaces.

Sandcastle Navigated Example

My example project on BitBucket:

https://bitbucket.org/gpriaulx/blog-topic-tutorial-htgrsandcastle