Updating Exchange distribution lists if you use a apple mac

I use a Apple Mac with outlook 2016 (v15). One of the problems i have is that I can’t update Exchange based email distribution lists. I haven’t been able find a way to do this from outlook but you can update them using Microsofts Exchange Web (OWA)  that most companies run for employees.

I believe this is office 365 version of OWA, other versions may be different

If you have access to OWA (Outlook Web App), then after you log in

Click on Options, then See All options in the top right hand corner

Click on Groups


Enter the name of the group in the right hand section of the screen that says “Public Groups | OWN

When the group shows up, double click on it

Click on membership

Then you can click on the add or remove, to edit the list.


Comparing Garmin Edge 305 to Nexus 6P with strava

Today i recorded the same route from both a garmin edge 305 and using strava on my nexus 6p. The Garmin appears to win. The Garmin on on a flybar mount on front of my bike and the phone was in a ziplock bag  in my back jersey pocket, so it might be interesting to do some further testing with it in a similar position to the garmin. The garmin data is fed to garmin connect, which is in turn fed into strava.

Nexus 5P and Strava

Garmin 305

The garmin output appears to be less jaggy and follows the road or the path more accurately

I also have an ANT+ usb adaptor on the phone and the heart rate monitor was emmm poor

Nexus 6p

Garmin Edge 305

I had thought about switching to just using my phone, but the garmin is giving me consistently  better gps mapping.

Uploading ride with GPS routes to garmin 305

My goal was to be able to get turn notifications on routes so i don’t have to constantly look at cue sheets.

This is a work in progress and may change

First create your route on ridewithgps.

Then click on the export tab, choose GPX Route (.gpx)

Open the .gpx file in Garmin Base Camp and right click on the route name and say send to device.

On the Garmin Edge 305 it should now show up under Navigation -> Routes

Garmin Edge 305

The case on my Garmin edge 305 has been separating for while now, and today during a ride it completely came apart. I was doing some research to see what kind of glue i should use to reattach it, but I also noticed that this unit is a little different from the ones on the Garmin Edge repair blogs like http://bikepathwarrior.blogspot.com/2011/09/repairing-garmin-edge-205-or-305.html and https://www.jimcarson.com/2009/replacing-the-battery-in-a-garmin-edge-305/

The edge 305 had issues with the daughter board with the battery disconnecting from the garmin when it was bumped. So I was a little surprised why mine continued to work while the case was separated. My unit is a replacement unit from Garmin so it looks like it has had some modifications before they sent it to me

So the first thing to notice is that the black and red wire from the battery are soldered onto the main board and don’t rely on the jumper board and spring connectors


Then there appears to be a red shim between the daughter board and the back case.


This unit has obviously been worked on since the foil had already been moved to get at the components under it, I just lifted it to show what was under it, i didn’t work the foil loose it was already like that.


another of the main board


and the battery

I am tempted to see if i can get a replacement battery before i reseal the unit.

Create a linux partition bigger than 2TB

If you use fdisk to create a partition on your disc that is larger than 2TB you will only see the first 2TB of the disc. Instead you should use parted.

sudo parted /dev/sdb
GNU Parted 2.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt                                                      
Warning: The existing disk label on /dev/sdb will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? yes                                                               
(parted) mkpart primary ext4 0% 100%
(parted) p                                                                
Model: ATA WDC WD60EFRX-68M (scsi)
Disk /dev/sdb: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt

Number  Start   End     Size    File system  Name     Flags
 1      1049kB  6001GB  6001GB               primary
sudo mkfs.ext4 /dev/sdb1

Extending a lennox icomfort thermostat: part 2

I setup up an android emulator, side loaded the icomfort app, installed charles proxy, installed the cert from charles proxy, started the emulator with an http proxy, then started sniffing the https traffic. This all took me a while to get all working, but after a lot of banging of heads i finally started to get the unencrypted packets from the app.

The website and the android app use a completely different API. i converted my first attempt at a logging app to the same API that android uses and now have a much cleaner app. Have a look at https://github.com/bruman/ruby-icomfort for the full code.

I added a lot of debug statements so you can see the json that gets passed back and forward, then it starts print

"date, Cool_Set_Point, Head_Set_Point, Indoor_temp, Fan_Mode, Indoor_Humidity, System_Status, Operation_Mode"
"/Date(1416870002787+0000)/,78.0,68.0,71.0,auto,47,idle,heat or cool"

part 1 of my post about interfacing with the icomfort



Installshield: Prompt user for a license file, then copy it


I need to add a prompt to an installshield project that asks the user where the license key file is, then copy the file to the INSTALLDIR location.

This is going to be a fairly complex thing, First I am going to create an install script function that copies the file, then I am going to create two custom actions, one that executes the CopyLicenseFile installscript file, the other prompts for the File location using  a file browser. Then I am going to create a new dialog that will call the FileBrowse custom action.

I am assuming you have already created a basic MSI project.


I used the following references






Expand out Behavior and Logic, and click on InstallScript

Click on the Installscript, then right click on Files and choose New Script File

Comment out the same code

//export prototype MyFunction(HWND);


// Function: MyFunction
// Purpose: This function will be called by the script engine when
// Windows(TM) Installer executes your custom action (see the "To
// Do," above).
//function MyFunction(hMSI)
 // To Do: Declare local variables.

 // To Do: Write script that will be executed when MyFunction is called.


We are going to create an extry point function called ExFn_CopyLicenseFile Copy and Paste into the Setup.rul,

#include "ifx.h"
// Function: ExFn_CopyLicenseFile
// Purpose: This function will be called by the script engine when
// Windows(TM) Installer executes your custom action (see the "To
// Do," above).
// The Function reads from the Property LICENSEFILE and INSTALLDIR, then copies the
// Include Ifx.h for built-in InstallScript function prototypes.
#include "Ifx.h"
export prototype ExFn_CopyLicenceFile(HWND);
function ExFn_CopyLicenceFile(hMSI)
 NUMBER nResult;
 STRING licenseFilePath;
 NUMBER licenseFilePathBuffer;
 licenseFilePathBuffer = MAX_PATH;
 if(MsiGetProperty(hMSI, "LICENSEFILE", licenseFilePath, licenseFilePathBuffer) == ERROR_SUCCESS) then
 SprintfBox(INFORMATION,"Deferred Execution","The value of LICENSEFILE is %s",licenseFilePath);
 SprintfBox(INFORMATION,"Deferred Execution","The value of INSTALLDIR is %s",INSTALLDIR);

 // Copy all files in the source directory, including files
 // in subdirectories, to the target directory.
 nResult = CopyFile(licenseFilePath, INSTALLDIR + "license.lic"); 
 // Report the results of the copy operation.
 switch (nResult)
 case 0:
 MessageBox ("File successfully copied.", INFORMATION);
 MessageBox ("A target directory could not be created.", SEVERE);
 MessageBox ("Insufficient memory.", SEVERE);
 MessageBox ("Insufficint disk space.", SEVERE);
 MessageBox ("Unable to open the input files in "+ INSTALLDIR +".",
 MessageBox ("Unable to copy the source files.", SEVERE);
 MessageBox ("A target file already exists and cannot be overwritten.",
 MessageBox ("An unspecified error occurred.", SEVERE);

I have left in the MessageBox and the SprintfBox lines to aid in debugged, and would be removed for your production version.

You should now have file -> Setup.rul and Functions -> ExFn_CopyLicenseFile

Custom Actions

Expand out Behavior and Logic, then click Custom Actions and Sequences

Right click on Custom Actions and choose New InstallScript

Change name to “CopyLicenseFile”

Set ‘Function Name’ to ExFn_CopyLicenseFile

Set install Exec Sequence to After MsiConfigureService

Set the ‘Install Exec Condition’ to ‘NOT Installed AND NOT PATCH’ this will mean it only runs if the Product is not installed and this isn’t a Patch

Create another Custom action, New MSI DLL, Stored in Binary Table

Rename to FileBrowse


In the right hand pane

DLL Filename: <ISProductFolder>\redist\language independent\i386\FileBrowse.dll
Function Name: FileBrowse
Return Processing: Synchronous (Ignores exit code)
In-Script Execution: Immediate Execution
Execution Scheduling: Always execute
For all other settings, leave the default values. The value of the MSI Type Number setting should be 65.

Create Properties

Expand out Behavior and Logic, and click on Property Manager

Click on New

Rename to LICENSEFILE, since this starts with a CAPITAL it creates a global property that can be referenced later.


Create Custom Dialog

Expand out User Interface and click on Dialogs

Find the DestinationFolder Dialog,

Right Click and clone

Rename to LicenseFileLocation

We are doing to repeat the following steps for a number of resources, the goal is to create a new STRING property for each string we are changing, so we don’t accidentally change the strings in other dialogs.

Click on LicenFileLocation, English (United States)

Click on the string Destination Folder so it is highlighted

Click in the Text field where is says Destination Folder

Click on the …

Then Cick on New

Change Value to License File

Repeat for “Click next to install


Change Text to “Click Next to install, or click Change to change the source of the License File”, remember to do the three dot and then new to create a new string, or you will also change the value in the dialog you cloned.

Change “Install [ProductName] to:” to “Install [ProductName] License File:”

Click on  [INSTALLDIR]

Change Property to LICENSEFILE

Change Text: to [LICENSEFILE], remeber the three dots and create new string

Click on LicenseFileLocation -> Behavior

Click on ChangeFolder

Change SpawnDialog to DoAction, and Argument to FileBrowse

Change [_BrowseProperty] to [LICENSEFILE] and Argument to [IS_BROWSE_FILEBROWSED]

Click on Back

Change NewDialog to “Destination Folder”

Click on DestinationFolder -> Behavior

Click on Next

Change NewDIalog to LicenseFileLocation

Click on SetupType -> Behavior

Click on Back

Change NewDialog to LicenseFileLocation


Now the moment of truth, build and test, Why are not setting a default license file so it is pulling the default value from the property which is “0”

Click on Change…


Succcess 🙂

Installshield Register.Net DLLs

My task is I need to register  a .net dll as part of the install.

First thing I am going to do is Create a Basic MSI Project

Approach 1

Create a component with just the .net dll in it

Make sure you have clicked the Installation Designer Tab, then expand out ‘Organization’, then select ‘Setup Design’, then select TestDLLRegister_Files

Right Click, choose ‘New Component’

Now expand out TestComonent, and choose ‘Files’

right click and choose ‘Add’ and select the dll you want to register.

Now it should show up in the files listing.

To set the .dll to be the keyfile, select the dll, then choose ‘Set Key File’

You will now see the key icon next to the DLL

Click on TestComponent

You should see

Change the .net Interop to yes

Installshield in the background is using regasm /regfile to create a file that contains the registry changes needed, then includes those changes as part of the install.

For some reason, perhaps that I am installing a 32bit component on a 64bit machine, this didn’t work as expected. After install the target machine contained all the registry enteries that the regasm /regfile creates but it didn’t work, I have read that some DLL’s perform post registration actions the run when you run RegAsm.exe VirtualCam.dll /nologo /codebase but don’t get captured when you run RegAsm.exe VirtualCam.dll /nologo /codebase /regfile

Approach 2

Run a .bat file to register the files.

Create 2 batch files, one that registers the dll and the other that unregisters

C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe VirtualCam.dll /nologo /codebase


C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /unregister /nologo VirtualCam.dll

Create a new Component

Expand out the new component you created Test2Comonent, and click on ‘Files’

Add files

Make sure it will install your files to [INSTALLDIR] by clicking on Test2Component and checking it says ‘Destination’ ‘[INSTALLDIR]’

Expand out ‘Behavior and Logic’ and choose ‘Custom Actions and Sequences’

Right click on custom actions

Choose new exe -> Path references a file

Set ‘Working Directory’ to ‘INSTALLDIR’

Set ‘File Name & Command LIne’ to ‘[SystemFolder]cmd.exe /c /install.bat’

Set ‘Return Processing’ to  ‘Syncronous (Check exit code)’

Set ‘In-Script Execution’ to ‘Immediate Execution’

Set ‘Execution Secheduling’ to ‘Always execute’

This should give you an MSI type of 34

Change the Install Exec Sequence to ‘After InstallFinalize’

Set the ‘Install Exec Condition’ to ‘NOT Installed AND NOT PATCH’ this will mean it only runs if the Product is not installed and this isn’t a Parch

Rename the Custom Action to ‘RegisterDLL’

Repeat for  UnRegisterDLL, except this time you are executing uninstall.bat

This time the ‘Install Exec Sequence’ is “After RemoveIniValues’ and ‘Install Exec Condition’ is “Remove ~=”ALL” so this runs only when all components have been removed and the app is being uninstalled.

Now Assuming everything worked you will see the black dos box during the install and your DLL will be registered.