DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: IDEA: Convert Radio Frequency scan Data for 3 Manufacturers Data structures  (Read 19,253 times)

floydlloyd

  • Supporting Member
  • Joined in 2019
  • **
  • Posts: 5
Hi all,

I am an Audio Engineer at a Concert Hall and frequently use Wireless Microphone technology. I have to co-ordinate the Radio Frequency assignments to avoid interference.
There are 3 main Manufacturers of this gear, and they use different .csv file structures for the data imported into their equipment to generate usable non interfering frequency selections.
I've written a Power Shell script that takes the .csv output of a very common handheld Radio Frequency scanner and converts it to the proper structure for importation into the various Manufacturers equipment to ease the process of assigning Frequencies to Wireless Microphones.
I love it ... it works, but is clunky, and I'd like someone to make it robust and multi platform if possible. Currently to run it on Mac I load a Windows Virtual Machine and run it that way ... ugh
I do have a budget line for this so please let me know if it's too much for the "snacks" section .... if so, we can move it to an appropriate spot.

Cheers and thanks,

Lloyd B

Damn ... I forgot the Curly Brace on line 1148 ...

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
Not sure how relevant it is, but Powershell Core is (somewhat?) multi-platform.  Perhaps it's possible that what you have is already (or close to being?) multi-platform?

floydlloyd

  • Supporting Member
  • Joined in 2019
  • **
  • Posts: 5
Hi Ewemoa,

I would really like to be able to release this to the Audio community as a gift to those who would find it useful. To that end  I'd want it to be as simple as ... "run this" if possible.

In it's current form, there is a niggling issue where a file selection dialog popup appears behind the main window and unless you know it's there, the thing appears to be locked up. I was unable to solve it in a reasonable amount of time and got frustrated.

From what I've read it could run on Mac with some tweaking  and effort on the end users part to install stuff on the Mac.

I don't have knowledge of any language, but seem to be able to at least intrinsically understand the concept of programming. It was very mentally taxing and time consuming for me to constantly refer to the Powershell documentation and find existing snippets to borrow. I'd also hate to be the person who wrote something so insecure that it could takeover the machine or some dumb thing like that.

That "hidden" dialog is a real pain, as others who have tested it for me have gotten stumped.

I suppose I could be happier if someone were to at least help solve that issue and maybe find a straightforward way to load the proper libraries and run it on a Mac as simply as possible.

I think the script itself is reasonably commented to give someone an Idea what I'm trying to do.

Thanks for the inspiration to explain things a little further.

Damn ... I forgot the Curly Brace on line 1148 ...

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
Below are some possibly relevant thoughts, perhaps others will jump in with better suggestions / corrections.

If you're looking for something that doesn't involve additionally installing something and be multi-platform, I guess Powershell Core isn't going to do as that would also need to be installed.  Also, not everything written for the original Windows Powershell is going to run with Powershell Core -- this very much depends on the code in question though.

One general alternative path is a rewrite in something like Node.js (+ nexe), Nim, or something else which has the practical option of producing an executable for each platform you have an interest in deploying to.  Some of these options may result in a much larger download though -- unfortunately, it can often be the case that the ones that are easier to write the code for tend to produce larger files.

Depending on the details of what your code does, there may be another alternative that might work.  It's the idea of writing a web-based app (though it could be stored in local files, so you wouldn't need network access to run it) that runs in a web browser.

Without seeing and working with the code in question a bit though, it's not clear which alternative might be appropriate and how much work it might be to carry out.

Do you mind posting the code for others to examine?  Perhaps if the details can be studied, someone can give a better assessment about what might be involved.
« Last Edit: August 06, 2019, 02:16 AM by ewemoa »

Shades

  • Member
  • Joined in 2006
  • **
  • Posts: 2,954
Java has support for all operating systems. But might be overkill and an extra software dependency, which may be a problem for some.

There is software that is able to do such conversions. Quite some time ago I had to take look into the Bizztalk Server software from Microsoft to make the output of one piece of middleware to fit into another piece of middleware. While that was a fruitless endeavor (and way too expensive), the concept behind it might actually be helpful in the situation the OP describes.

The Bizztalk software allowed you to create adapters that take the output from one piece of software and "feed" that to an adapter for the other piece of software and have these pieces of software communicating directly. Those adapters could be made with a GUI and once created, they would function indefinitely. Bizztalk could do the same with files and lots of other types of data. Now, Bizztalk is a very expensive proposition, but there is an alternative called: FlowHeater Designer, which does use the concept of adapters and allows you to create them in a visual way. FlowHeater Designer is not nearly as extensive as BizzTalk is, but that is reflected in the price.

From what I understand is that content restructuring in a csv file is required. It would require 3 adapters to be created (one for each Manufacturer) and the FlowHeater software would be able to convert the content between these adapters, each generating a file: content_<manufacturer.name>.csv, ready to be imported into the software from each manufacturer. How to do that automatically within the Mac operating system is up to you. I make it a point to not work with any Apple gear, whenever I can think of a reason no to. 

You can try their freeware version to see if this type of software can actually help out. I have no affiliation with this software and no real experience with it either. But as a concept I do see possibilities.
The easy path is usually downhill...

floydlloyd

  • Supporting Member
  • Joined in 2019
  • **
  • Posts: 5
Thanks you two. I am away from my desk for the next couple days but will post the script and my description file, and a test .csv to be operated on as soon as I get back.

Damn ... I forgot the Curly Brace on line 1148 ...

floydlloyd

  • Supporting Member
  • Joined in 2019
  • **
  • Posts: 5
Hi everyone,

Thanks for replying.

I've attached the script and some documentation with a folder of .csv files to use as test files. They were generated by the Handheld Spectrum analyzer and are representative of real data but there was very little radio activity so the actual variance in numbers is limited. Doesn't look like much when plotted on a graph but will be sufficient to test the script.

I also remembered that I'd like to add a "selectable on startup of script" function ... the ability to select a . csv and convert it between formats and appropriately name and save the output. csv file.

So it would be ... Script starts by asking "what do you want to do?"
1. Create. csv files from an RF Explorer scan
2. Convert .csv between existing manufacturer created scans

Industry folks have asked me for this feature as they generally use the manufacturers actual wireless Mic receiver to do the scans (not the handheld analyzer that generated these test files) and the machine outputs a. csv in that manufacturers corresponding format.

I suppose I could revisit my powershell skills LOL and add this function in, but have been very busy at the Concert Hall and haven't had much time to get it done.

Hope that makes sense and that someone will take this on :-)
Damn ... I forgot the Curly Brace on line 1148 ...

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
There's now the Avalonia Project which provides a cross-platform UI solution for PowerShell (using XAML), (Windows, Linux, OSX), currently in beta but it shouldn't be hard to add a simple GUI to the script.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: August 07, 2019, 05:50 PM by 4wd »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
In it's current form, there is a niggling issue where a file selection dialog popup appears behind the main window and unless you know it's there, the thing appears to be locked up. I was unable to solve it in a reasonable amount of time and got frustrated.

From here System.Windows.Forms.OpenFileDialog always ontop - add a check for how the script was run and set $ShowHelp appropriately:

Code: ( powershell)
function Read-OpenFileDialog([string]$WindowTitle, [string]$InitialDirectory, [string]$Filter = "All files (*.*)|*.*", [switch]$AllowMultiSelect)
{
    Add-Type -AssemblyName System.Windows.Forms
    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $ShowHelp = $false
# See https://community.idera.com/database-tools/powershell/ask_the_experts/f/learn_powershell_from_don_jones-24/13493/system-windows-forms-openfiledialog-always-ontop
    if ($Host.name -eq "ConsoleHost") {$ShowHelp = $true}
    $openFileDialog.Title = $WindowTitle
    if (![string]::IsNullOrWhiteSpace($InitialDirectory)) { $openFileDialog.InitialDirectory = $InitialDirectory }
    $openFileDialog.Filter = $Filter
    if ($AllowMultiSelect) { $openFileDialog.MultiSelect = $true }
    $openFileDialog.ShowHelp = $ShowHelp    # Without this line the ShowDialog() function may hang depending on system configuration and running from console vs. ISE.
    $openFileDialog.ShowDialog() > $null
    if ($AllowMultiSelect) { return $openFileDialog.Filenames } else { return $openFileDialog.Filename }
}
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
Below are some observations and notes.

I tried the script out on a Windows 10 Pro box, but didn't notice dialog boxes being behind things.  Script execution was tested both from Windows Explorer as well as from a Powershell window.  It might be helpful to be able to replicate the issue -- perhaps it's for particular versions of Windows?

For running a test, one of the files from the TestFilesFromRFexplorer directory was selected.  It appears that all files in that directory get wiped by the end of the script.  I wonder if that is desirable behavior.  Also noticed some error output, but I did find a .zip file that appeared to contain the original file along with 2 converted ones.

Regarding running on macos, I looked a bit into 4wd's Avalonia idea, and came across: https://github.com/ironmansoftware/psavalonia "Avalonia bindings for PowerShell".  The supported versions of Powershell there look like Powershell Core though, so I tried running the script via Powershell Core.  The result was a fair number of error messages so I stopped its execution.

I also tried creating a simple python script to open a file dialog and tried packaging and running this on Windows and macos using PyInstaller.  Interestingly enough, there was no problem with the dialog being behind things on Windows, but on macos there was.  It appears to be something that other folks have encountered and although I found multiple work-arounds, none of them worked for my particular environment (though apparently some of them do work for other folks).  (On a side note, my experience with macos (OS X, etc.) over the years has been that backward compatibility of certain types of things is not particularly a high priority, with adjustments sometimes being necessary when there are new OS releases, so even if something were found to work, it might be good to keep in mind that future OS releases might necessitate updates.  Perhaps it's misleading to single out Apple in this regard.)

Regarding "Convert .csv between existing manufacturer created scans", perhaps if this general conversion portion were implemented, the current script might benefit from being based on it.  If someone were to start on this though, may be it would be better to consider Powershell Core or something else more multi-platform friendly, rather than Windows Powershell.

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
I tried the script out on a Windows 10 Pro box, but didn't notice dialog boxes being behind things.  Script execution was tested both from Windows Explorer as well as from a Powershell window.  It might be helpful to be able to replicate the issue -- perhaps it's for particular versions of Windows?

Interestingly, I always had one of its dialogs open behind other windows, (either the OpenFile or the final Retry/Cancel), until I added the above run check.

The Retry/Cancel dialog still opens behind other windows sometimes.

The other problem, which I believe is related to the use of the Show-Command cmdlet, is that selecting Cancel still opens the OpenFile dialog.

Quote
Regarding running on macos, I looked a bit into 4wd's Avalonia idea, and came across: https://github.com/ironmansoftware/psavalonia "Avalonia bindings for PowerShell".  The supported versions of Powershell there look like Powershell Core though, so I tried running the script via Powershell Core.  The result was a fair number of error messages so I stopped its execution.

Due to the use of Show-Command, it tries to create a Window using WPF, (by the looks), and fails under PowerShell Core, (doesn't exist) - you get the errors in PoShCore regardless of whether Avalonia is installed or not.

Quote
Regarding "Convert .csv between existing manufacturer created scans", perhaps if this general conversion portion were implemented, the current script might benefit from being based on it.

This would be a better idea, I might get a chance to look at it later and try and isolate the relevant routines, (still overseas on a low-powered laptop atm).
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: August 12, 2019, 10:35 AM by 4wd »

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
Interestingly, I always had one of its dialogs open behind other windows, (either the OpenFile or the final Retry/Cancel), until I added the above run check.

The Retry/Cancel dialog still opens behind other windows sometimes.

At least one of us can reproduce at least some of the time :)

Quote
The other problem, which I believe is related to the use of the Show-Command cmdlet, is that selecting Cancel still opens the OpenFile dialog.

Ah, I hadn't noticed this.

Quote
I might get a chance to look at it later and try and isolate the relevant routines, (still overseas on a low-powered laptop atm).

Do you think a Powershell Core implementation would make sense?

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Do you think a Powershell Core implementation would make sense?


Yes, definitely ... but since I've only used Windows PowerShell up til now ...

2019-08-14 10_13_42.png

2019-08-14 10_17_17.png

The below is functionally similar to the original PoSh script, the changes are:
  1. Put almost everything into Functions so they can be transplanted into other scripts.
  2. Added a WPF GUI (the implemented version is just something simple but more than doubles the size of the script) - it would benefit from having a ListBox that shows the selected files and a TextBox that shows the progress of the operation.  I kept it simple so as to not invest too much time into something that might be replaced with either, for example, an Avalonia based interface or some other language/GUI, (eg. Python).
  3. Added the ability to convert between RF Explorer, Sennheiser, and Shure input CSVs.  For example, select a Sennheiser file, select the Shure output option, hit Start.
  4. Options to either delete the original files and create a distribution archive.

NOTE: In my limited testing it worked fine but there are most likely bugs and there is no error checking, (the original script didn't have any either).

Tested on: Windows 10 Pro x64, PowerShell 5.1.18362.145, .NET 4.8

Broken down into sections, you have:
  • Global variables - there are three, two of them are defined later in the script by prefacing with $global:
  • Functions - file request and working directory creation, conversions, archive creation
  • GUI - everything else plus what happens when you click the buttons

RFExplorer.ps1
Code: ( powershell)
<# This form was created using POSHGUI.com  a free online gui designer for PowerShell
.NAME
    .\RFExplorer.ps1
#>

# Global variables
$initMessage = 'This script lets you browse to and select the pertinent .csv spectrum scan files that were output by your RF Explorer device, sort them by creation time, join them together and output 2 seperate files plus the original un-modified scan files into a newly created subdirectory named with the current date and time.

1. SHURE-importable
	Shure Wireless workbench accepts .csv files consisting of
	2 columns (no Headers) -> Frequency in MHz,Level in DBm
	(columns seperated by a comma)
		492.6,-103
		492.625,-96
		492.65,-102
2. SENNHEISER-Importable
	Sennheiser Wireless Systems Manager is more complicated. They expect a descriptive 2 column header then 3 columns of data -> Frequency in KHz;;Level in DB (columns seperated by a semi-colon)

		Receiver;01
		Date/Time;$lastwrittentime
		RFUnit;dB
		Owner;$FirstName $LastName
		ScanCity;$ScanCity
		ScanComment;
		ScanCountry;$ScanCountry
		ScanDescription;$ScanDescription
		ScanInteriorExterior;$ScanInteriorORExterior
		ScanLatitude;
		ScanLongitude;
		ScanName;$ScanName
		ScanPostalCode;$ScanPostalCode

		Frequency Range [kHz];$FreqRangeL;$FreqRangeH;$FreqSpan
		Frequency;RF level (%);RF level
		492600;;4
		492625;;11
		492650;;5

The $variables in the Sennheiser header get pulled from the info you enter into an initial popup dialog so you can archive AND/OR upload a zip file of the original RF Explorer scan chunks along with the 2 formatted files and a descriptive text file to an online database of venue scans from around the world    http://www.bestaudio.com/spectrum-scans/
I am using Nuts AboutNets Touchstone Pro Software $49US   http://nutsaboutnets.com/touchstone/    to interact with the RF Explorer for setting scan parameters and actually running the scans. The native software that comes with RF explorer can do everything but I found it time consuming to break the spectrum down into smaller chunks to increase resolution'

Function Get-Files {
  # Show an Open File Dialog and return the files selected by the user.
  $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
    InitialDirectory = $scanDirectory
#    InitialDirectory = [Environment]::GetFolderPath('MyDocuments') 
    Filter = 'RF Explorer Files|*.csv|All Files|*.*'
    MultiSelect = $true
  }

  $null = $FileBrowser.ShowDialog()

  if ($FileBrowser.FileNames.Count -eq 0) {
    return
  } else {
    $RFexplorerDataDirectory = Split-Path $FileBrowser.FileNames[0] -Parent
    $global:lastwrittentime = (Get-ItemProperty -Path $FileBrowser.FileNames[0]).LastWriteTime.tostring("MM-MMMM-dd-yyyy-hh-mm-ss")
  }

  $currentdatetime = Get-Date -f ("MM-MMMM-dd-yyyy-hh-mm-ss")
  $destDir = "$($RFexplorerDataDirectory)\$($currentdatetime)"
  New-Item -ItemType Directory "$($destDir)" | Out-Null

  # Copy/Move selected files to Destination directory
  for ($i = 0; $i -lt $FileBrowser.FileNames.Count; $i++) {
  # Clear out non-CSV files from destination directory
    if ($CheckBox1.CheckState) {
      Move-Item $FileBrowser.FileNames[$i] -dest "$destDir"
    } else {
      Copy-Item $FileBrowser.FileNames[$i] -dest "$destDir"
    }
  }
  return $destDir
}

Function Senn-RFE {
  param (
    [double]$n1,
    [double]$n2
  )
  if ($n1 -gt 1000) {
    $n1 /= 1000
    $n2 -= 107
  }
  return "$($n1);$($n2)"
}

Function ConvertTo-RFE {
  param (
    [string]$file
  )
  Get-Content $file | `
    Where-Object {$_ -match '^\d+.+'} | `
    Foreach-Object {$_ -replace ";;" , ";"} | `
    Foreach-Object {$_ -replace "," , ";"} | `
    ForEach-Object {$fields = $_.Split(";") ;
      Out-File -FilePath "intermediate.tmp" -InputObject (Senn-RFE $fields[0] $fields[1]) -Append -Encoding utf8}
}

Function ConvertTo-Shure {
  param (
    [string]$file
  )
  (Get-Content $file) | `
    Foreach-Object {$_ -replace " -" , "-"} | `
    Foreach-Object {$_ -replace ";" , ","} | `
    Set-Content -Path "SHURE-Importable-$($lastwrittentime).csv"
}


Function ConvertTo-Sennheiser {
  param (
    [string]$file
  )
  # Create a new array to temporarily house the dBm to dB conversion data that comes later
  $BeingModified = New-Object System.Collections.ArrayList

  (Get-Content $file) | `
#    Foreach-Object {$_ -replace "(\d{3})\.(\d{2})" , '$1$2'} |
#    Foreach-Object {$_ -replace "(-\d{3})(\d{2})" , '$1.$2'} |
    Foreach-Object {$_ -replace ";" , ";;"} | `
    Foreach-Object {$_ -replace "," , ";;"} | `
# Change the RF Level data from dBm to Sennheisers' dB by adding 107
    Foreach-Object {$_
      $fields = $_.Split(";")
      $freq = [double]$fields[0]*1000
      #$blank = $fields[1]
      $dBm = [double]$fields[2]
      [double]$dB = $dBm + 107
      # Create array with the new values to use later to replace things in the new output file
      [void]$BeingModified.Add("$freq;;$dB")
    }

  $BeingModified | Set-Content $file
  $wwbbasefile = "$($destDirectory)\$($file)"

  # Get FreqRange and Span Data into variables

  $FreqRangeL = Get-Content $wwbbasefile | Select -First 1
  $FreqRangeH = Get-Content $wwbbasefile | Select -Last 1
  $FreqRange_ = Get-Content $wwbbasefile | Select -Last 2

  # parse the CSV data back into separate variables, one for each column

  $dataArrayL = $FreqRangeL.Split(";")
  $FreqRangeL = $dataArrayL[0]

  $dataArrayH = $FreqRangeH.Split(";")
  $FreqRangeH = $dataArrayH[0]

  $dataArray_ = $FreqRange_.Split(";")
  $FreqRange_ = $dataArray_[0]

  # Calculate the frequency span
  $FreqSpan = $FreqRangeH - $FreqRange_

  # Define the Header required for Sennheiser Wireless Systems Manager to be able to read the .csv file

  $sennheader=
@"
Receiver;01
Date/Time;$lastwrittentime
RFUnit;dB
Owner;$($TextBox1.Text) $($TextBox2.Text)
ScanCity;$($TextBox3.Text)
ScanComment;
ScanCountry;$($ComboBox1.Text)
ScanDescription;$($TextBox4.Text)
ScanInteriorExterior;$($ComboBox2.Text)
ScanLatitude;
ScanLongitude;
ScanName;$($TextBox5.Text)
ScanPostalCode;$($TextBox6.Text)
Frequency Range [kHz];$FreqRangeL;$FreqRangeH;$FreqSpan
Frequency;RF level (%);RF level
"@


  # Insert the header text into  a text file
  $sennheader | Set-Content sennheader.txt

  # Join the header file and .csv data into final output file
  Get-Content sennheader.txt, $wwbbasefile | Set-Content "SENNHEISER-Importable-$($lastwrittentime).csv"
}

Function Create-Distribution {
  # Create a directory to store the zipped results for upload to Pet Erskines database
  New-Item -ItemType Directory "$destDirectory\For Distribution" | Out-Null
  $zipName = "$($destDirectory)\For Distribution\$($TextBox3.Text)-$($TextBox7.Text)-$($ComboBox1.Text)-$($TextBox8.Text)-$($lastwrittentime)-$($TextBox1.Text)-$($TextBox2.Text).zip"
  Compress-Archive -Path "$($destDirectory)\*.csv" -DestinationPath "$($zipName)"
}

Add-Type -AssemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form                            = New-Object system.Windows.Forms.Form
$Form.ClientSize                 = '400,500'
$Form.text                       = "RFTSSE"
$Form.TopMost                    = $false

$Label1                          = New-Object system.Windows.Forms.Label
$Label1.text                     = "First Name:"
$Label1.AutoSize                 = $true
$Label1.width                    = 25
$Label1.height                   = 10
$Label1.location                 = New-Object System.Drawing.Point(25,20)
$Label1.Font                     = 'Microsoft Sans Serif,10'

$TextBox1                        = New-Object system.Windows.Forms.TextBox
$TextBox1.multiline              = $false
$TextBox1.width                  = 210
$TextBox1.height                 = 20
$TextBox1.location               = New-Object System.Drawing.Point(160,18)
$TextBox1.Font                   = 'Microsoft Sans Serif,10'

$Label2                          = New-Object system.Windows.Forms.Label
$Label2.text                     = "Last Name:"
$Label2.AutoSize                 = $true
$Label2.width                    = 25
$Label2.height                   = 10
$Label2.location                 = New-Object System.Drawing.Point(25,46)
$Label2.Font                     = 'Microsoft Sans Serif,10'

$TextBox2                        = New-Object system.Windows.Forms.TextBox
$TextBox2.multiline              = $false
$TextBox2.width                  = 210
$TextBox2.height                 = 20
$TextBox2.location               = New-Object System.Drawing.Point(160,43)
$TextBox2.Font                   = 'Microsoft Sans Serif,10'

$Label3                          = New-Object system.Windows.Forms.Label
$Label3.text                     = "Scan City:"
$Label3.AutoSize                 = $true
$Label3.width                    = 25
$Label3.height                   = 10
$Label3.location                 = New-Object System.Drawing.Point(25,70)
$Label3.Font                     = 'Microsoft Sans Serif,10'

$TextBox3                        = New-Object system.Windows.Forms.TextBox
$TextBox3.multiline              = $false
$TextBox3.width                  = 210
$TextBox3.height                 = 20
$TextBox3.location               = New-Object System.Drawing.Point(160,68)
$TextBox3.Font                   = 'Microsoft Sans Serif,10'

$Label4                          = New-Object system.Windows.Forms.Label
$Label4.text                     = "Scan Country:"
$Label4.AutoSize                 = $true
$Label4.width                    = 25
$Label4.height                   = 10
$Label4.location                 = New-Object System.Drawing.Point(25,95)
$Label4.Font                     = 'Microsoft Sans Serif,10'

$ComboBox1                       = New-Object system.Windows.Forms.ComboBox
$ComboBox1.width                 = 210
$ComboBox1.height                = 20
@("Afghanistan","Albania","Algeria","American Samoa","Andorra","Angola","Anguilla","Antarctica","Antigua and Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia and Herzegovina","Botswana","Bouvet Island","Brazil","British Antarctic Territory","British Indian Ocean Territory","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Canton and Enderbury Islands","Cape Verde","Cayman Islands","Central African Republic","Chad","Chile","China","Christmas Island","Cocos [Keeling] Islands","Colombia","Comoros","Congo - Brazzaville","Congo - Kinshasa","Cook Islands","Costa Rica","Croatia","Cuba","Cyprus","Czech Republic","Côte d’Ivoire","Denmark","Djibouti","Dominica","Dominican Republic","Dronning Maud Land","East Germany","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Guiana","French Polynesia","French Southern Territories","French Southern and Antarctic Territories","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guadeloupe","Guam","Guatemala","Guernsey","Guinea","Guinea-Bissau","Guyana","Haiti","Heard Island and McDonald Islands","Honduras","Hong Kong SAR China","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Johnston Island","Jordan","Kazakhstan","Kenya","Kiribati","Kuwait","Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau SAR China","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Martinique","Mauritania","Mauritius","Mayotte","Metropolitan France","Mexico","Micronesia","Midway Islands","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Myanmar [Burma]","Namibia","Nauru","Nepal","Netherlands","Netherlands Antilles","Neutral Zone","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","Niue","Norfolk Island","North Korea","North Vietnam","Northern Mariana Islands","Norway","Oman","Pacific Islands Trust Territory","Pakistan","Palau","Palestinian Territories","Panama","Panama Canal Zone","Papua New Guinea","Paraguay","People's Democratic Republic of Yemen","Peru","Philippines","Pitcairn Islands","Poland","Portugal","Puerto Rico","Qatar","Romania","Russia","Rwanda","Réunion","Saint Barthélemy","Saint Helena","Saint Kitts and Nevis","Saint Lucia","Saint Martin","Saint Pierre and Miquelon","Saint Vincent and the Grenadines","Samoa","San Marino","Saudi Arabia","Senegal","Serbia","Serbia and Montenegro","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Georgia and the South Sandwich Islands","South Korea","Spain","Sri Lanka","Sudan","Suriname","Svalbard and Jan Mayen","Swaziland","Sweden","Switzerland","Syria","São Tomé and Príncipe","Taiwan","Tajikistan","Tanzania","Thailand","Timor-Leste","Togo","Tokelau","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Turks and Caicos Islands","Tuvalu","U.S. Minor Outlying Islands","U.S. Miscellaneous Pacific Islands","U.S. Virgin Islands","Uganda","Ukraine","Union of Soviet Socialist Republics","United Arab Emirates","United Kingdom","United States","Unknown or Invalid Region","Uruguay","Uzbekistan","Vanuatu","Vatican City","Venezuela","Vietnam","Wake Island","Wallis and Futuna","Western Sahara","Yemen","Zambia","Zimbabwe","Åland Islands") | ForEach-Object {[void] $ComboBox1.Items.Add($_)}
$ComboBox1.location              = New-Object System.Drawing.Point(160,93)
$ComboBox1.Font                  = 'Microsoft Sans Serif,10'

$Label5                          = New-Object system.Windows.Forms.Label
$Label5.text                     = "Scan Description:"
$Label5.AutoSize                 = $true
$Label5.width                    = 25
$Label5.height                   = 10
$Label5.location                 = New-Object System.Drawing.Point(25,121)
$Label5.Font                     = 'Microsoft Sans Serif,10'

$TextBox4                        = New-Object system.Windows.Forms.TextBox
$TextBox4.multiline              = $false
$TextBox4.width                  = 210
$TextBox4.height                 = 20
$TextBox4.location               = New-Object System.Drawing.Point(160,119)
$TextBox4.Font                   = 'Microsoft Sans Serif,10'

$Label6                          = New-Object system.Windows.Forms.Label
$Label6.text                     = "Scan Int or Ext:"
$Label6.AutoSize                 = $true
$Label6.width                    = 25
$Label6.height                   = 10
$Label6.location                 = New-Object System.Drawing.Point(25,146)
$Label6.Font                     = 'Microsoft Sans Serif,10'

$ComboBox2                       = New-Object system.Windows.Forms.ComboBox
$ComboBox2.width                 = 210
$ComboBox2.height                = 20
@('Interior','Exterior') | ForEach-Object {[void] $ComboBox2.Items.Add($_)}
$ComboBox2.location              = New-Object System.Drawing.Point(160,144)
$ComboBox2.Font                  = 'Microsoft Sans Serif,10'

$Label7                          = New-Object system.Windows.Forms.Label
$Label7.text                     = "Scan Name:"
$Label7.AutoSize                 = $true
$Label7.width                    = 25
$Label7.height                   = 10
$Label7.location                 = New-Object System.Drawing.Point(25,172)
$Label7.Font                     = 'Microsoft Sans Serif,10'

$TextBox5                        = New-Object system.Windows.Forms.TextBox
$TextBox5.multiline              = $false
$TextBox5.width                  = 210
$TextBox5.height                 = 20
$TextBox5.location               = New-Object System.Drawing.Point(160,170)
$TextBox5.Font                   = 'Microsoft Sans Serif,10'

$Label8                          = New-Object system.Windows.Forms.Label
$Label8.text                     = "Scan Postcode:"
$Label8.AutoSize                 = $true
$Label8.width                    = 25
$Label8.height                   = 10
$Label8.location                 = New-Object System.Drawing.Point(25,197)
$Label8.Font                     = 'Microsoft Sans Serif,10'

$TextBox6                        = New-Object system.Windows.Forms.TextBox
$TextBox6.multiline              = $false
$TextBox6.width                  = 210
$TextBox6.height                 = 20
$TextBox6.location               = New-Object System.Drawing.Point(160,195)
$TextBox6.Font                   = 'Microsoft Sans Serif,10'

$Label9                          = New-Object system.Windows.Forms.Label
$Label9.text                     = "Scan State/Province:"
$Label9.AutoSize                 = $true
$Label9.width                    = 25
$Label9.height                   = 10
$Label9.location                 = New-Object System.Drawing.Point(25,222)
$Label9.Font                     = 'Microsoft Sans Serif,10'

$TextBox7                        = New-Object system.Windows.Forms.TextBox
$TextBox7.multiline              = $false
$TextBox7.width                  = 210
$TextBox7.height                 = 20
$TextBox7.location               = New-Object System.Drawing.Point(160,220)
$TextBox7.Font                   = 'Microsoft Sans Serif,10'

$Label10                         = New-Object system.Windows.Forms.Label
$Label10.text                    = "Scan Venue:"
$Label10.AutoSize                = $true
$Label10.width                   = 25
$Label10.height                  = 10
$Label10.location                = New-Object System.Drawing.Point(25,247)
$Label10.Font                    = 'Microsoft Sans Serif,10'

$TextBox8                        = New-Object system.Windows.Forms.TextBox
$TextBox8.multiline              = $false
$TextBox8.width                  = 210
$TextBox8.height                 = 20
$TextBox8.location               = New-Object System.Drawing.Point(160,245)
$TextBox8.Font                   = 'Microsoft Sans Serif,10'

$Button1                         = New-Object system.Windows.Forms.Button
$Button1.text                    = "Select files ..."
$Button1.width                   = 300
$Button1.height                  = 30
$Button1.location                = New-Object System.Drawing.Point(50,280)
$Button1.Font                    = 'Microsoft Sans Serif,10'

$Button2                         = New-Object system.Windows.Forms.Button
$Button2.text                    = "Start"
$Button2.width                   = 95
$Button2.height                  = 30
$Button2.location                = New-Object System.Drawing.Point(50,320)
$Button2.Font                    = 'Microsoft Sans Serif,10'

$Label11                         = New-Object system.Windows.Forms.Label
$Label11.text                    = "Output"
$Label11.AutoSize                = $true
$Label11.width                   = 25
$Label11.height                  = 10
$Label11.location                = New-Object System.Drawing.Point(228,330)
$Label11.Font                    = 'Microsoft Sans Serif,10'

$RadioButton1                    = New-Object system.Windows.Forms.RadioButton
$RadioButton1.text               = "Sennheiser"
$RadioButton1.AutoSize           = $true
$RadioButton1.width              = 104
$RadioButton1.height             = 20
$RadioButton1.location           = New-Object System.Drawing.Point(213,350)
$RadioButton1.Font               = 'Microsoft Sans Serif,10'

$RadioButton2                    = New-Object system.Windows.Forms.RadioButton
$RadioButton2.text               = "Shure"
$RadioButton2.AutoSize           = $true
$RadioButton2.width              = 104
$RadioButton2.height             = 20
$RadioButton2.location           = New-Object System.Drawing.Point(213,370)
$RadioButton2.Font               = 'Microsoft Sans Serif,10'

$RadioButton3                    = New-Object system.Windows.Forms.RadioButton
$RadioButton3.text               = "RF Explorer"
$RadioButton3.AutoSize           = $true
$RadioButton3.width              = 104
$RadioButton3.height             = 20
$RadioButton3.location           = New-Object System.Drawing.Point(213,390)
$RadioButton3.Font               = 'Microsoft Sans Serif,10'

$RadioButton4                    = New-Object system.Windows.Forms.RadioButton
$RadioButton4.text               = "Combined"
$RadioButton4.AutoSize           = $true
$RadioButton4.width              = 104
$RadioButton4.height             = 20
$RadioButton4.Checked            = $true
$RadioButton4.location           = New-Object System.Drawing.Point(213,410)
$RadioButton4.Font               = 'Microsoft Sans Serif,10'

$CheckBox1                       = New-Object system.Windows.Forms.CheckBox
$CheckBox1.text                  = "Delete originals"
$CheckBox1.AutoSize              = $false
$CheckBox1.width                 = 120
$CheckBox1.height                = 20
$CheckBox1.location              = New-Object System.Drawing.Point(50,370)
$CheckBox1.Font                  = 'Microsoft Sans Serif,10'

$CheckBox2                       = New-Object system.Windows.Forms.CheckBox
$CheckBox2.text                  = "Create archive"
$CheckBox2.AutoSize              = $false
$CheckBox2.width                 = 120
$CheckBox2.height                = 20
$CheckBox2.Checked               = $true
$CheckBox2.location              = New-Object System.Drawing.Point(50,390)
$CheckBox2.Font                  = 'Microsoft Sans Serif,10'

$Button3                         = New-Object system.Windows.Forms.Button
$Button3.text                    = "Information"
$Button3.width                   = 100
$Button3.height                  = 30
$Button3.location                = New-Object System.Drawing.Point(150,440)
$Button3.Font                    = 'Microsoft Sans Serif,10'

$Form.controls.AddRange(@($Label1,$Label2,$Label3,$Label4,$Label5,$Label6,$Label7,$Label8,$Label9,$Label10,$Label11,$TextBox1,$TextBox2,$TextBox3,$TextBox4,$TextBox5,$TextBox6,$TextBox7,$TextBox8,$ComboBox1,$ComboBox2,$Button1,$Button2,$Button3,$RadioButton1,$RadioButton2,$RadioButton3,$RadioButton4,$CheckBox1,$CheckBox2))

# Select Files Button
$Button1.Add_Click({
  # Get the directory the working files are in
  $global:destDirectory = Get-Files

  # Destination directory becomes working directory, so Push it
  Push-Location -Path "$destDirectory"

  # Sort RF Explorer created .csv files by date and time, concat them into a temporary file
  Get-ChildItem *.csv | sort LastWriteTime | % {$(Get-Content $_)} | Set-Content joined.tmp
})

# Start Button
$Button2.Add_Click({
  if ($RadioButton1.Checked) {
    ConvertTo-RFE joined.tmp
    ConvertTo-Sennheiser intermediate.tmp
  }
  if ($RadioButton2.Checked) {
    ConvertTo-RFE joined.tmp
    ConvertTo-Shure intermediate.tmp
  }
  if ($RadioButton3.Checked) {
    ConvertTo-RFE joined.tmp
  }
  if ($RadioButton4.Checked) {
    ConvertTo-Shure joined.tmp
    ConvertTo-Sennheiser joined.tmp
  }

  # Remove non-CSV files
  Remove-Item -Path "$($destDirectory)\*" -Exclude *.csv

  # Create archive for distribution
  if ($CheckBox2.CheckState) {
    Create-Distribution
  }

  Pop-Location
})

# Information Button
$Button3.Add_Click({
  $result = [Microsoft.VisualBasic.Interaction]::MsgBox($initMessage, 'OKOnly,SystemModal,Information', 'RFTSSE')
})

[void]$Form.ShowDialog()
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: August 14, 2019, 10:16 AM by 4wd »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Four problems became apparent in PowerShell Core (Windows) for the above code:
  • Initial window size could not be set
  • The font used was not recognised
  • The FileBrowser did not work (locked up the console)
  • The Information window relies on VB routines

It ran and opened a GUI but you couldn't do anything.

I've installed PowerShell Core under Windows Subsytem for Linux (WSL) so I can have a play, (also installed on a RasPi I've got with me) - doesn't run at all under PoShCore (Linux), to be expected.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
I like the single UI approach.  Have been thinking whether the ability to load / save the fields at the top might make sense.  That might also make the functionality more easily packaged as a command line script for use with other tools.

Nice work with the new features and modularization.  The latter should make it easier to study and perhaps it will also facilitate work on Powershell Core compatibility. 

I guess one aspect to consider for multi-platform compatibility is file paths.  Possibly also line endings?  May be Avalonia or Powershell Core has paid some attention to these (and other) issues...

Hope to test it soon.

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Could avoid the GUI altogether and revert to a series of Read-Host prompt/answer inputs plus include the ability to run as a standard command if all parameters are fulfilled on the command line.

Would be the quickest way to make it portable.

W.r.t. filepaths, PowerShell (Core) is pretty agnostic when it comes to using / or \ - either will do, plus it sees multiple occurrences, (eg. ////), as just a single occurrence.

For example, the below are all the same path as far as PoSh (Core) is concerned:
D:\test\data\test.txt
d:test/data/test.txt
d:\\\\\\\\test///////data\\\\test.txt
d:\\\\\\\\test//\\\\data\/\/\/\/test.txt

It makes this aspect of PoSh scripts OS agnostic ... something they got exactly right :Thmbsup:
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

ewemoa

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 2,922
    • Plugin Coding Medal
    • Participated in NANY Challenge Three Times
Did some testing, though not with Powershell Core.  When launched from a Powershell terminal, the initial dialog wasn't behind any windows, but it didn't have focus.

The generated SENNHEISER ".csv" file I looked at didn't have an extra blank line between the header and the rest of the data.  IIRC, the original script puts a blank line between the header and the data.  Don't know if that makes any difference.

Other than that, it seemed pretty good to me.

Could avoid the GUI altogether and revert to a series of Read-Host prompt/answer inputs plus include the ability to run as a standard command if all parameters are fulfilled on the command line.

Would be the quickest way to make it portable.

I guess there could be a GUI wrapper around this -- in fact, there could be platform-specific wrappers.

Quote
W.r.t. filepaths, PowerShell (Core) is pretty agnostic when it comes to using / or \ - either will do, plus it sees multiple occurrences, (eg. ////), as just a single occurrence.

For example, the below are all the same path as far as PoSh (Core) is concerned:
D:\test\data\test.txt
d:test/data/test.txt
d:\\\\\\\\test///////data\\\\test.txt
d:\\\\\\\\test//\\\\data\/\/\/\/test.txt

It makes this aspect of PoSh scripts OS agnostic ... something they got exactly right :Thmbsup:

Nice.  I wouldn't be surprised if some cross-platform projects start using Powershell Core scripts instead of maintaining separate .bat and .sh files.  Perhaps some do already, though perhaps Powershell Core isn't yet installed on that many non-Windows systems...

floydlloyd

  • Supporting Member
  • Joined in 2019
  • **
  • Posts: 5
Thanks you all.

Although it may seem I have abandoned you I haven't. We are back into a busy time at the Concert Hall already.
I will try to put a bit of time into this each week. but it will be somewhat sporadic it seems.
That single GUI box is fantastic.
Thanks again for even entertaining the idea of helping with this.

Cheers

Damn ... I forgot the Curly Brace on line 1148 ...

Original address: https://www.donationcoder.com/forum/index.php?topic=48333.0