Converting RTF-HTML – Not possible in a thread?

Been working on an application that needed to convert some RTF to HTML. Initially I thought this would be a reasonably simple requirement, and hoped that .Net might even include such a function to do this. Alas, I was being too optimistic.

So, trusting Google, ended up on this post from Matthew Manela –

Put that it, built the project, and ran on my UI thread, all works fine.

Put the same code in a background worker process or thread, and you will get an error: The calling thread must be STA, because many UI components require this.

The converter above unfortunately uses the built in RichTextBox component to perform a RTF-XAML conversion as the first step in the whole conversion process.

So, if anyone knows of a way that I can go from RTF-HTML in a separate thread from the UI, I would love to hear from you.

Be the first to like.
Posted in | Leave a comment

Ping Host with a Log File

Another potentially useful script here. It pings a host and records the output in a log file. The ping continues until you press Ctrl+C to stop it. This is useful for running in a background monitoring connectivity response times to a host and seeing if there is any network dropout.

Ping is no guarantee of performance, but it does give some idea if you have some underlying network problem over an extended period.

Run from the command line using the following format:

Ping_With_Log.vbs C:\GooglePing.txt
'Script to ping a host and record the output to a log file. 
'Craig Tolley
'Version 1.0 - 09/10/2013 - Initial Release
'Version 2.0 - 10/01/2014 - Complete rewrite to make significantly more usable and readable. 

'-------------------  START SCRIPT -------------------

'Check the provided arguments
If WScript.Arguments.Count = 2 Then
	HostToPing = WScript.Arguments(0)
	LogFileName = WScript.Arguments(1)
	Wscript.Echo "Invalid number of arguments detected. " & Chr(13) & Chr(13) & _
				 "Usage: Ping_With_Log.vbs HostToPing LogFileName" & Chr(13) & Chr(13) & _
				 "The host to ping can either be an IP address or resolvable host name" & Chr(13) & Chr(13) & _
				 "The LogFile can either be just a filename, in which case it will be created in the current directory, or a full folder path and file name" & Chr(13) & Chr(13) & _
				 "e.g Ping_With_Log.vbs C:\GooglePing.txt"
End If

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell   = CreateObject("Wscript.Shell")
Set objLogFile = objFSO.OpenTextFile(logfilename, 8, True)

'Run the command
strCommand = "%comspec% /c ping -t " & HostToPing
Set objExec   = objShell.Exec(strCommand)

Wscript.Echo "Ping with Error Log has started. To stop collecting Ping data press Ctrl+C"

'Keep writing the output of the application until Ctrl+C is pressed to cancel the ping
Do While objExec.StdOut.AtEndOfStream <> True
	objLogFile.WriteLine(Date & " " & Time & " " & objExec.StdOut.ReadLine)

'Open the log file for viewing
strCommand = "notepad.exe " & LogFileName

Be the first to like.
Posted in General Stuff | Leave a comment

Using Enum with ComboBox and setting Combobox value –

This is my take on setting a combobox to use an enum which has both a description and key value set. It also shows how this works when trying to assign a value to the combobox.

Enum MyLogEnum
Error = 1
Warning = 2
Information = 3
End Enum

ComboBox_LogLevel.DataSource = System.Enum.GetValues(GetType(MyLogEnum))

And to assign a numeric value to the Combobox and make it display correctly:

ComboBox_LogLevel.SelectedItem = DirectCast(SourceIntValue, MyLogEnum)

Unfortunately, I could not find an equally as elegant way of doing the same thing using a ComboBox that was part of a Datagrid View, so ended up rewriting the Enum as a Dictionary like this:

Dim LoggingLevelsList As New Dictionary(Of String, Integer)
For Each enumValue As Integer In [Enum].GetValues(GetType(MyLogEnum))
LoggingLevelsList.Add([Enum].GetName(GetType(MyLogEnum), enumValue), enumValue)
DataGridCombo.DataSource = New Windows.Forms.BindingSource(LoggingLevelsList, Nothing)
DataGridCombo.DisplayMember = "Key"
DataGridCombo.ValueMember = "Value"

With this in the Datagridview Combobox, you do not need to do any casting from the source integer.

If someone has a better way for Enums on a DataGridView ComboBox, I would really like to hear them.

Be the first to like.
Posted in Programming, | Leave a comment

Recursively Delete Empty Folders – VBScript

Ok, if you use your favourite search engine to look up a recursive deletion of empty folders, you will more than likely come up with a lot of results. I did. However by the end of the first page, I hadn’t found what I needed, so made up my own.

The special bits about this script:

  1. It forces you to use cscript and the command line, meaning that you won’t have to keep clicking OK to the prompts.
  2. It checks if there are any thumbs.db or desktop.ini files in the folders first, as these would otherwise stop the deletion.
  3. It tells you at the end if there were any errors.

Nothing particularly ground breaking, just more useful to me.

So, here it is. My advice – when running the script run it and pipe the results to a file – that way you can quickly search the file for the word ‘Error’ to see what didn’t work. For example:

cscript C:\Scripts\DeleteEmptyFolders.vbs > C:\Scripts\Results.txt

And here is the script:

'Script to delete all empty folders within a given directory. 
'Recursively searches through to make sure that folders that just contain empty folders are also removed.
'Also removed desktop.ini and thumbs.db files if they exist to accurately remove empty folders.  
'Craig Tolley
'Version 1.0 - 27/12/2013 - Initial Release

'-------------------  START SCRIPT -------------------
Option Explicit
On Error Resume Next

'Check we are running from the command line and using cscript. 
If Not LCase( Right( WScript.FullName, 12 ) ) = "\cscript.exe" Then
	WScript.Echo("You must use cscript and run this script from the command line." & Chr(13) & "e.g cscript.exe DeleteEmptyFolders.vbs")
End If

'Define some variables and bits. 
Dim objFSO, strFolderPath, intErrorCount
Set objFSO = CreateObject("Scripting.FileSystemObject")
intErrorCount = 0

'Ask user for the folder to tidy up. Check they entered something and that what they entered is actually a valid folder. 
strFolderPath = InputBox("Enter the path of the directory to clean up")
strFolderPath = Trim(strFolderPath)
If Len(strFolderPath) = 0 Then 
	WScript.Echo "No path entered. Exiting"
End If
If (objFSO.FolderExists(strFolderPath)) = False Then
	WScript.Echo "The path entered is either invalid or cannot be found. Please check and try again."
End If

'Run the recursive cleanup
RecursiveDeleteEmptyFolders strFolderPath

'Give the user back some information. 
WScript.Echo "--------------------------------------------------------------------"
WScript.Echo "Finished Cleanup of " & strFolderPath
If intErrorCount > 0 Then WScript.Echo "There were " & intErrorCount & " errors during the operation"
WScript.Echo "--------------------------------------------------------------------"

'Sub to recursively delete all empty folders. 
Sub RecursiveDeleteEmptyFolders(ByVal strDirectory)
	On Error Resume Next
	Dim objFolder, objSubFolder
	Set objFolder = objFSO.GetFolder(strDirectory)
	WScript.Echo "Checking Folder: " & strDirectory & ". Contains " & objFolder.Files.Count & " files and " & objFolder.SubFolders.Count & " folders."

	'If the RemoveDesktopIni or RemoveThumbsDB Flag is set to True then remove any files called Desktop.ini or thumbs.db
	If objFSO.FileExists(strDirectory & "\desktop.ini") Then 
		objFSO.DeleteFile(strDirectory & "\desktop.ini")
		If Err Then
			WScript.Echo "Error deleting:" & strDirectory & "\desktop.ini" & " - " & Err.Description
			intErrorCount = intErrorCount + 1
		End If
   	End If
	If objFSO.FileExists(strDirectory & "\thumbs.db") Then 
		objFSO.DeleteFile(strDirectory & "\thumbs.db")
			If Err Then 
				WScript.Echo "Error deleting:" & strDirectory & "\thumbs.db" & " - " & Err.Description
				intErrorCount = intErrorCount + 1
		End If
   	End If
	'Now check if the folder contains any files. 
	If objFolder.Files.Count = 0 Then
		'Then check if there are any subfolders. 
		If objFolder.SubFolders.Count = 0 Then
			'Check that the subfolders do not begin with a tilde, and if they do not, delete the folder. 
			If Left(objFolder.Name,1) <> "~" Then
				WScript.Echo "Deleting: " & objFolder.Path
				If Err Then 
					WScript.Echo "Error deleting:" & objFolder.Name & " - " & Err.Description
					intErrorCount = intErrorCount + 1
				End If
			End If
			'Subfolders found, so go through each of those. 
			For Each objSubFolder in objFolder.SubFolders
				RecursiveDeleteEmptyFolders objSubFolder.Path
		End If
		'Files have been found in the folder, but check any subfolders anyway
		For Each objSubFolder in objFolder.SubFolders
			RecursiveDeleteEmptyFolders objSubFolder.Path
	End If
End Sub

1 person found this post useful.
Posted in VBScript | Leave a comment

MagicISO with Intel ICH10R RAID Array

Was having trouble getting MagicISO to install on my Windows 7 x64 Professional machine that I had just rebuilt. It worked fine before I installed new hard disks, but not now.

My new HDD have been installed in a RAID1 configuration using the built in Intel ICH10R RAID controller. This involved giving Windows a driver when installing (the built in one on the RTM CD does not load correctly and causes setup failures).

My CD drive is also on the same ICH10R bus, so a filter had been set on the drivers in the registry. This was stopping the successful installation of virtual CD drives which did not use the Intel bus.

The solution in this case is to remove the filters.

  1. Open regedit.
  2. Browse to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Class\{4D36E965-E325-11CE-BFC1-08002BE10318}
  3. Rename UpperFilters to UpperFilters.old
  4. Rename LowerFilters to LowerFilters.old
  5. Reboot your machine.

MagicISO should then install successfully and be able to create virtual drives.

The values that I had in my registry entries were: LowerFilters:iaStorF, UpperFilters: GEARAspiWDM. The first is created by the Intel RAID controller card, and the second is created when iTunes is installed.

After you have rebooted and installed MagicISO, you may need to rename UpperFilters1 back to the original name so that iTunes will load without an error.


Be the first to like.
Posted in Windows 7 | Leave a comment

VMWare Player: Set Default VM Location

The GUI of VMWare Player does not allow you to change the default location of your new VMs. However, a modification to the preferences file can.

Open up the following file in your favorite text editor:


Add in the following line, changing the path to your desired location:

prefvmx.defaultvmpath = "D:\Virtual Machines\VMWare Player"

Save, restart VMWare Player, and your new location should work when creating a new VM.

This has been tested on VMWare Player 6.

1 person found this post useful.
Posted in General Stuff | Leave a comment

Microsoft Lync Conversation Cleanup

New mini-project complete and available here:

This tool removes duplicated conversation parts from Microsoft Outlook Conversation History, making your history smaller and more manageable.

The main window of the application, in this case showing a completed run.

The main window of the application, in this case showing a completed run.

Be the first to like.
Posted in Lync, Microsoft Office | Leave a comment

Group Policy Loopback Troubleshooting

Once again I have just spent around an hour troubleshooting something which on the face of it should just work – Group Policy Loopback Processing.

A sure fire way to a headache.

Anyway, this post saved me from my frustration.

Be the first to like.
Posted in Active Directory | Leave a comment

PowerShell 3: Add Multi-line TXT Record to DNS

This had me stumped for about 30 minutes, until I finally worked out the correct syntax to make this all work.

I was looking for a way to create a TXT record on my DNS server. The data though is a multi-line record – and had to be multi-line for the server to understand the response. Single line are easy – but the multi-line really threw me.

The trick is `r`n – this inserts a carriage return and line feed into the string. I was using a apostrophe at first and wondering why it wasn’t working. It isn’t, it is a grave accent, ASCII 96.

So, as an example:

$txtdata = "line1`r`nline2`r`nline3"
Add-DnsServerResourceRecord -ZoneName testdomain.internal -Name MyNewTXTRecord -Txt -DescriptiveText $txtdata

This gives you a record that looks like this in Windows DNS.


It would appear at the minute that this command limits the length of the DescriptiveText parameter to 255 charactors. This is maximum string length, per line. PowerShell interprets this as the maximum length overall though.

Be the first to like.
Posted in Server 2012 | Leave a comment

Untangle 9.3.2 on Hyper-V 2012

I have just been playing with getting an Untangle ( server up and running on a Windows Server 2012 Hyper-V install. Looking at this as a possible replacement to ISA 2004 on our current Windows SBS 2003 install.

I had read up various articles of problem that have been encountered with network adapters, no mouse and install problems – all of which appeared to be on Hyper-V 2008.

So, I took the jump (server is still in development, so plenty of scope for testing stuff out). I created a VM using the following:

  • 1 processor
  • 768mb RAM (dynamic)
  • 20gb VHDX fixed disk
  • 2 legacy NICs, bound to 2 different VLAN’s through the same virtual switch

Booted it up, and it picked up the install CD straight away. It passed through all of the hardware pre-requisite checks and was installed and at the config screen in about 10 mins.

I was very surprised to find that the mouse worked out of the box – no integration services installed. So, that made installation a touch easier.

Once I had identified which NIC i had assigned to which VLAN, I managed to get it hooked up to the Internet, where it picked up all the appliances. I installed the Lite pack (saved clicking loads of apps).

Now that I was able to get in I decided to see if the VM would support using a standard virtual network adapter, so changed the internal one, and rebooted. And from this, I can confirm that Untangle 9.3.2 does not detect a standard NIC in Hyper-V. So, reverted back, reset the network configuration and we were back online.

I hooked up my PC to the internal VLAN, and was able to get on the Internet, no problem at all. My statistics in Untangle started going up as I spent some time doing some general browsing.

My next challenge is going to be seeing if I can install the Integration Services pack, or if indeed it is actually built in like some distro’s are. Debian is not listed on the MS support guests website, but it can’t hurt trying. Here is a list of the support guest OS on 2012:

It’s too early to say if performance wise it is any good running on a VM. As it is working, I should imagine I will put it on test for a couple of weeks and see what happens. Will also monitor how it goes once I get a couple more VM’s set up, running Server 2012 with Exchange and another running Server 2008 with SharePoint. That will add some heat to the situation and then see if Untangle can still keep up.

Will post again once I have a change to test the Integration Services and give an update on performance when we get into some more serious testing.


Having now got this set up a bit more, and actually in a production environment, I have some more information on two things:

The Mouse

Now that it is in production, I am using a remote desktop connection to administer the Hyper-V host server. I can connect to the host server, and open up my Untanghle serve in the VM Connection – and the mouse does not work. If i plug back in a mouse to the actual server, I can use the mouse inside Untangle. So I guess if you are using a KVM solution to control your Hyper-V server then you will probably be ok, if not, you may be a touch stuck.

VLAN’s and Legacy Networking

The Internet connection is on a separate VLAN to the guest WIFI network, but the same switch. I wasn’t looking to put in any extra NIC’s to my Hyper-V host, so experimented with VLAN assignment.

I configured a NIC team (Broadcom adapters) on the Hyper-V host, with no VLAN assignments at that level, as per MS best practice. A Virtual Switch then connects to this, again with no VLAN assignment.

Of my two legacy NIC’s on the VM, one was configured for the public WIFI vlan, and one configured for the Internet VLAN. I rebooted the Untangle server and again this works. I was able to connect to the Untangle server from clients on the public wifi and be prompted with the desired capture portal page.

Interestingly, all of the NIC’s show as disconnected in Untangle, despite it working. I am guessing that must be an issue with how the VM is presenting NIC status to Linux.

Integration Services

As yet, I have not managed to get Integration Services installed.

Be the first to like.
Posted in Hyper-V, Internet Security, Server 2012 | 4 Comments
  • Tags

  • Categories

  • My LinkedIn Profile

    To see my LinkedIn profile, click here:

    Craig Tolley
  • April 2014
    M T W T F S S
    « Feb    
  • Meta

  • Top Liked Posts

    Powered by WP Likes

Swedish Greys - a WordPress theme from Nordic Themepark.