Creating a Yes/No MessageBox in a NuGet install/uninstall script

Sometimes getting a little feedback during the install/uninstall process of a NuGet package could be really useful. Instead of accounting for all possible ways to install your NuGet package for every user, you can simplify the installation by clarifying with the user what they want.

This example shows how to generate a windows yes/no message box to get input from the user in the PowerShell install or uninstall script.

We’ll use the prompt on the uninstall to confirm if the user wants to delete a custom setting that the initial install placed in their configuration.  Obviously you could use the prompt in any way you want.


The objects of the message box are generated similar to the controls in the code behind of a WinForm.

At the beginning of your script enter this:

param($installPath, $toolsPath, $package, $project)
 
# Set up path variables
$solutionDir = Get-SolutionDir
$projectName = (Get-Project).ProjectName
$projectPath = Join-Path $solutionDir $projectName
 
################################################################################################
# WinForm generation for prompt
################################################################################################
function Ask-Delete-Custom-Settings {
    [void][reflection.assembly]::loadwithpartialname("System.Windows.Forms") 
    [Void][reflection.assembly]::loadwithpartialname("System.Drawing")
 
    $title = "Package Uninstall"
    $message = "Delete the customized settings?"
        
    #Create form and controls
    $form1 = New-Object System.Windows.Forms.Form
    $label1 = New-Object System.Windows.Forms.Label
    $btnYes = New-Object System.Windows.Forms.Button
    $btnNo = New-Object System.Windows.Forms.Button
 
    #Set properties of controls and form
    ############
    #  label1  #
    ############
    $label1.Location = New-Object System.Drawing.Point(12,9)
    $label1.Name = "label1"
    $label1.Size = New-Object System.Drawing.Size(254,17)
    $label1.TabIndex = 0
    $label1.Text = $message
 
    #############
    #   btnYes  #
    #############
    $btnYes.Location = New-Object System.Drawing.Point(156,45)
    $btnYes.Name = "btnYes"
    $btnYes.Size = New-Object System.Drawing.Size(48,25)
    $btnYes.TabIndex = 1
    $btnYes.Text = "Yes"
 
    ###########
    #  btnNo  #
    ###########
    $btnNo.Location = New-Object System.Drawing.Point(210,45)
    $btnNo.Name = "btnNo"
    $btnNo.Size = New-Object System.Drawing.Size(48,25)
    $btnNo.TabIndex = 2
    $btnNo.Text = "No"
 
    ###########
    #  form1  #
    ###########
    $form1.ClientSize = New-Object System.Drawing.Size(281,86)
    $form1.Controls.Add($label1)
    $form1.Controls.Add($btnYes)
    $form1.Controls.Add($btnNo)    
    $form1.Name = "Form1"
    $form1.Text = $title
    
    #Event Handler
    $btnYes.add_Click({btnYes_Click})
    $btnNo.add_Click({btnNo_Click})
    
    return $form1.ShowDialog()
}
function btnYes_Click
{
    #6 = Yes
    $form1.DialogResult = 6
}
function btnNo_Click
{    
    #7 = No
    $form1.DialogResult = 7
}
################################################################################################

This has also wired up the click events to the form.  This is all it takes to create the message box.


Now we have to actually use the message box and get the user’s response or this is all pointless.  We’ll then delete the section of the application/web configuration called <Custom.Settings>

    [xml] $configXmlContent = Get-Content $configFile
 
    Write-Host "Please respond to the question in the Dialog Box."
    $dialogResult = Ask-Delete-Custom-Settings
    #6 = Yes
    #7 = No
    Write-Host "dialogResult = $dialogResult"
    if ($dialogResult.ToString() -eq "Yes")
    {
        Write-Host "Deleting customized settings"
        $customSettingsNode = $configXmlContent.configuration.Item("Custom.Settings")
        $configXmlContent.configuration.RemoveChild($customSettingsNode)
        $configXmlContent.Save($configFile)
    }
    if ($dialogResult.ToString() -eq "No")
    {
        Write-Host "Do not delete customized settings"
    }

The part where I check if ($dialog.Result.ToString() –eq “Yes”) could just as easily check the value for either 6 or 7 (Yes or No).  I just personally decided I liked this way better.

 


Shahzad Qureshi is a Software Engineer and Consultant in Salt Lake City, Utah, USA

His certifications include:

Microsoft Certified System Engineer
3CX Certified Partner
Global Information Assurance Certification – Secure Software Programmer – .NET

He is the owner of Utah VoIP Store at http://www.utahvoipstore.com/ and SWS Development at http://www.swsdev.com/ and publishes windows apps under the name Blue Voice.

Determining if you’re running on the build server with MSBuild – Easy way

When you're customizing MSBuild in building a visual studio project, it often becomes important to determine if the build is running on the build server or your development environment.

This information can change the way you set up path variables and other Conditional tasks.I've found many different answers online.

It seems like they all only worked under certain conditions, so none of them were guaranteed to be consistent.So here's the simplest way I've found that has not failed me yet.

  <PropertyGroup>
    <!-- Determine if the current build is running on the build server -->
    <IsBuildServer>false</IsBuildServer>
    <IsBuildServer Condition="'$(BuildUri)' != ''">true</IsBuildServer>
  </PropertyGroup>
 


Shahzad Qureshi is a Software Engineer and Consultant in Salt Lake City, Utah, USA

His certifications include:

Microsoft Certified System Engineer
3CX Certified Partner
Global Information Assurance Certification – Secure Software Programmer – .NET

He is the owner of Utah VoIP Store at www.UtahVoIPStore.com and SWS Development at www.swsdev.com and publishes windows apps under the name Blue Voice.

Confirming communication with an XBee radio and FEZ Cerbuino Bee

 

So I’ve decided to expand my horizons further into the world of Microcontrollers.  As a .NET engineer with little hardware experience I found that the learning curve to enter the hardware world has drastically decreased.

For my first attempt at deploying .NET code to a .NET Micro Framework compatible device I am simply trying to send anything from 1 XBee radio to a 2nd XBee radio that is connected to a FEZ Cerbuino Bee micro controller board.  The radios are not using WiFi, they are using the 802.15.4 standard which is for things like smart home automation using the ZigBee protocol.  But right now I’m not using ZigBee (I’m just sending plain ASCII characters through), therefore I will not explain the details of what ZigBee is or MESH networking or anything like that.  In a future blog post I’m sure I’ll get in to those.

Considerations

- I am using two laptops to do this exercise but that is not necessarily required.

- I am assuming you have already set up your XBee radios for basic communication.  I set them up from the tutorial in the popular book “Building Wireless Sensor Networks”.

[UPDATE] There is also a good step-by-step on setting up the XBee radios for communication at this link, although the link is for a different type of project, the section on the XBee radios is exactly what you need to do for this setup as well.  http://www.instructables.com/id/Use-xbees-series-2-to-control-a-motor/step2/set-the-firmware-on-the-xbees/http://www.instructables.com/id/Use-xbees-series-2-to-control-a-motor/step2/set-the-firmware-on-the-xbees/

- I am assuming you have properly installed the Microsoft .NET Micro Framework and the applicable GHI Electronics SDK

- Here is the hardware I’m using:

2 x XBee 2mW Wire Antenna - Series 2 (The XBee radios that will be communicating)

2 x XBee to USB adapter (to make the XBee radio connect via USB to my laptop)

1 x FEZ Cerbuino Bee (The XBee receiving the data will plug into this so my .NET code can listen to it)

image

(FEZ Cerbuino Bee with XBee radio plugged into it)


SETTING UP THE HARDWARE

1. First plug in the first XBee adapter to the XBee to USB adapter. image
(Left: XBee plugged into the XBee to USB Adapter, Right: An XBee to USB Adapter by itself)

2. Open the X-CTU software that comes with the XBee radio and read the modem configuration. blog2 

3. The first radio should be set as a ZigBee Coordinator AT. The 2nd radio (which will be plugged into the Cerbuino) will be a ZigBee Router AT. image 

4. Plug the 2nd XBee (The one set as your router) into the Cerbuino. WP_000634
(XBee radio plugged in to the Cerbuino)

5. In your project properties, be sure to set the deployment device to your hardware.  blog4blog5


WRITING THE CODE

6. Create a new Micro Framework Console application called XBeeReceive.
We are going to write all our code in the Main function of Program.cs
blog3

7. This code is a simplified mixture of misc. code I found online, with my own modifications.  The primary points of the code are as follows:

- Creating an OutputPort on the built in debug LED is always a good idea in any project.
OutputPort debugLED = new OutputPort((Cpu.Pin)FEZCerbuino.Pin.Digital.LED1,false);
- Using the SerialPort object, you can create a connection from the Cerbuino board to the XBee.  I connected to the XBee on COM1, but I don’t know if that’s hard coded or if that is configurable.  It just happened to work.

SerialPort xbeeSerialPort = new SerialPort("COM1",9600, Parity.None, 8, StopBits.One)

- Subscribing to the DataReceived event on the serial port object is where we make our connection between the two radios.
xbeeSerialPort.DataReceived += (sender, e) =>
    {
       //... Code here
    };
- At the end of the main function, you will always need to do this to be sure the program doesn’t just load in the microcontroller and immediately end.  As I have seen it so far in Micro Framework console apps, you generally have an infinite loop or event handler set up before calling this last.
Thread.Sleep(Timeout.Infinite);


8. Here is the complete code.  This will write each message sent from the first XBee to the Debug window, one message at a time. 

Since I am sending from the first XBee using a terminal program (The terminal built in to the X-CTU software) the data is getting sent one character at a time so it is outputting one character at a time.  To compensate for this I put a pause (Thread.Sleep) to let more characters build up in the buffer before I spit them out to the debug window.

 

Be sure to watch the LED on your Cerbuino and see it light up with each character that comes through.

using System;
using System.IO.Ports;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Math = System.Math;
using GHI.OSHW.Hardware;

namespace XBeeReceive
{
    public class Program
    {
        public static void Main()
        {
            OutputPort debugLED = new OutputPort((Cpu.Pin)FEZCerbuino.Pin.Digital.LED1,false);

            using(SerialPort xbeeSerialPort = new SerialPort("COM1",9600, Parity.None, 8, StopBits.One))
            {
                xbeeSerialPort.Open();
                
                const int bufferSize = 256;
                byte[] buffer = new byte[bufferSize];

                xbeeSerialPort.DataReceived += (sender, e) =>
                    {
                        //Pause to let buffer build up (so a full word can be sent and not just a character at a time
                        Thread.Sleep(2000);
                        int numberOfBytes = Math.Min(xbeeSerialPort.BytesToRead, bufferSize);
                        numberOfBytes = Math.Min(xbeeSerialPort.Read(buffer, 0, numberOfBytes), numberOfBytes);
                        if (numberOfBytes > 0)
                        {
                            StringBuilder sbDataReceived = new StringBuilder();
                            debugLED.Write(true);
                            for (int i = 0; i < numberOfBytes; i++)
                            {
                                sbDataReceived.Append(Convert.ToChar(buffer[i]).ToString());                                
                            }
                            debugLED.Write(false);

                            Debug.Print(sbDataReceived.ToString());
                        }
                    };

                Thread.Sleep(Timeout.Infinite);
            }
        }

    }
}

 


Shahzad Qureshi is a Software Engineer and Consultant in Salt Lake City, Utah, USA

His certifications include:

Microsoft Certified System Engineer
3CX Certified Partner
Global Information Assurance Certification – Secure Software Programmer – .NET

He is the owner of Utah VoIP Store at www.UtahVoIPStore.com and SWS Development at www.swsdev.com and publishes windows apps under the name Blue Voice.

Installing a VADTools design component into your 3CX Voice Application Designer toolbox

The 3CX Voice Application Designer is an innovative tool for creating IVR (Interactive Voice Response) Applications, or Voice Applications.  It is a familiar drag-and-drop experience that Visual Studio developers will get the hang of pretty quick.

Additionally, there are new 3rd party components released by BlueVoice, that are distributed though www.UtahVoIPStore.com

I thought I’d post a quick introduction to it, by showing how to install a component into you designer tool box.  In this example I am using the CommandLine component, which lets you call the command line from your voice application.


First, copy the ZIP file that came with your component to the root folder of your VAD project.
clip_image002[4]

Now extract the zip file into the root directory.
clip_image004[4]

The component will be in the root directory and the Libraries directory will have a new DLL file.
clip_image006[4]
clip_image008[4]

Open your VAD project and right-click on the project in project explorer to add the new component to your project.
clip_image010

Navigate to the root folder of your project and select the new component.
clip_image012

The component is now ready for you to use in your toolbox.
clip_image014