Initial commit - eDNC Special Character Fix
Real-time file watcher to strip invalid characters (0xFF, etc.) from DNC program files for CNC machine compatibility. Features: - Monitors folder for .pun files (configurable) - Automatically cleans files on create/modify - Configurable character removal - Retry logic for locked files - Session statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
130
README.md
Normal file
130
README.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# eDNC Special Character Fix
|
||||||
|
|
||||||
|
Real-time file watcher that automatically removes invalid special characters from DNC (Direct Numerical Control) program files.
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
Some legacy DNC systems and communication protocols add padding or termination bytes that modern CNC controllers cannot process correctly. Common problematic characters include:
|
||||||
|
|
||||||
|
| Byte | Hex | Name | Description |
|
||||||
|
|------|-----|------|-------------|
|
||||||
|
| 255 | 0xFF | Fill | Padding/fill character |
|
||||||
|
| 0 | 0x00 | NULL | Null character |
|
||||||
|
| 26 | 0x1A | SUB | Ctrl+Z / EOF marker |
|
||||||
|
| 127 | 0x7F | DEL | Delete character |
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
This utility monitors a folder for DNC files and automatically strips specified characters as soon as files are created or modified.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Copy the project folder to your DNC workstation
|
||||||
|
2. Edit `eDNC-SpecialCharFix.ps1` to set your watch folder (default: `C:\Dnc_Files\Q`)
|
||||||
|
3. Run `Run-eDNCFix.bat` or create a shortcut
|
||||||
|
|
||||||
|
### Run at Startup (Optional)
|
||||||
|
|
||||||
|
To run automatically at Windows startup:
|
||||||
|
|
||||||
|
1. Press `Win + R`, type `shell:startup`, press Enter
|
||||||
|
2. Create a shortcut to `Run-eDNCFix.bat` in the Startup folder
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
Double-click `Run-eDNCFix.bat` or run from PowerShell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\eDNC-SpecialCharFix.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Watch Folder
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\eDNC-SpecialCharFix.ps1 -WatchFolder "D:\DNC\Programs"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Different File Types
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\eDNC-SpecialCharFix.ps1 -FileFilter "*.nc"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remove Additional Characters
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Remove 0xFF, NULL, and SUB characters
|
||||||
|
.\eDNC-SpecialCharFix.ps1 -CharactersToRemove @(255, 0, 26)
|
||||||
|
```
|
||||||
|
|
||||||
|
### All Options
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\eDNC-SpecialCharFix.ps1 `
|
||||||
|
-WatchFolder "C:\Dnc_Files\Q" `
|
||||||
|
-FileFilter "*.pun" `
|
||||||
|
-IncludeSubfolders $true `
|
||||||
|
-CharactersToRemove @(255)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Default | Description |
|
||||||
|
|-----------|------|---------|-------------|
|
||||||
|
| WatchFolder | String | C:\Dnc_Files\Q | Folder to monitor |
|
||||||
|
| FileFilter | String | *.pun | File pattern to watch |
|
||||||
|
| IncludeSubfolders | Boolean | $true | Watch subdirectories |
|
||||||
|
| CharactersToRemove | Int[] | @(255) | Byte values to strip |
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
The script displays real-time activity:
|
||||||
|
|
||||||
|
```
|
||||||
|
========================================
|
||||||
|
eDNC Special Character Fix v1.0.0
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
Watch Folder: C:\Dnc_Files\Q
|
||||||
|
File Filter: *.pun
|
||||||
|
Subfolders: True
|
||||||
|
Removing bytes: 255 (0xFF)
|
||||||
|
|
||||||
|
Watching for files... Press Ctrl+C to stop
|
||||||
|
|
||||||
|
2025-12-12 08:30:15 | Created | PART001.pun
|
||||||
|
[CLEANED] Removed 3 byte(s)
|
||||||
|
2025-12-12 08:30:22 | Changed | PART002.pun
|
||||||
|
[OK] No special characters found
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Windows PowerShell 5.1 or later
|
||||||
|
- Read/Write access to the watch folder
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Watch folder does not exist"
|
||||||
|
Create the folder or specify a different path with `-WatchFolder`.
|
||||||
|
|
||||||
|
### "File locked" errors
|
||||||
|
The script retries up to 3 times if a file is locked. If errors persist, the file may be in use by another application.
|
||||||
|
|
||||||
|
### Script doesn't detect files
|
||||||
|
- Verify the file extension matches `-FileFilter`
|
||||||
|
- Check that `-IncludeSubfolders` is set correctly
|
||||||
|
- Ensure the script has permissions to the folder
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
| Version | Date | Changes |
|
||||||
|
|---------|------|---------|
|
||||||
|
| 1.0.0 | 2025-12-12 | Initial release |
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
GE Aerospace - Rutland
|
||||||
14
Run-eDNCFix.bat
Normal file
14
Run-eDNCFix.bat
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@echo off
|
||||||
|
:: eDNC Special Character Fix Launcher
|
||||||
|
:: Runs the PowerShell script with appropriate execution policy
|
||||||
|
|
||||||
|
title eDNC Special Character Fix
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Starting eDNC Special Character Fix...
|
||||||
|
echo.
|
||||||
|
|
||||||
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0eDNC-SpecialCharFix.ps1" %*
|
||||||
|
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
188
eDNC-SpecialCharFix.ps1
Normal file
188
eDNC-SpecialCharFix.ps1
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
eDNC Special Character Fix - Real-time file watcher to strip invalid characters from DNC files.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Monitors a specified folder for DNC program files (.pun, .nc, etc.) and automatically
|
||||||
|
removes special characters (0xFF and others) that cause issues with CNC machines.
|
||||||
|
|
||||||
|
Some legacy DNC systems and communication protocols add padding or termination bytes
|
||||||
|
that modern CNC controllers cannot process correctly.
|
||||||
|
|
||||||
|
.PARAMETER WatchFolder
|
||||||
|
The folder to monitor for DNC files. Default: C:\Dnc_Files\Q
|
||||||
|
|
||||||
|
.PARAMETER FileFilter
|
||||||
|
File pattern to watch. Default: *.pun
|
||||||
|
|
||||||
|
.PARAMETER IncludeSubfolders
|
||||||
|
Whether to watch subfolders. Default: $true
|
||||||
|
|
||||||
|
.PARAMETER CharactersToRemove
|
||||||
|
Array of byte values to strip from files. Default: @(255) for 0xFF
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\eDNC-SpecialCharFix.ps1
|
||||||
|
Runs with default settings, watching C:\Dnc_Files\Q for *.pun files
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\eDNC-SpecialCharFix.ps1 -WatchFolder "D:\DNC\Programs" -FileFilter "*.nc"
|
||||||
|
Watches D:\DNC\Programs for .nc files
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\eDNC-SpecialCharFix.ps1 -CharactersToRemove @(255, 0, 26)
|
||||||
|
Removes 0xFF, NULL, and SUB (Ctrl+Z) characters
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Author: GE Aerospace - Rutland
|
||||||
|
Version: 1.0.0
|
||||||
|
Date: 2025-12-12
|
||||||
|
|
||||||
|
Common problematic characters:
|
||||||
|
- 0xFF (255) - Padding/fill character
|
||||||
|
- 0x00 (0) - NULL character
|
||||||
|
- 0x1A (26) - SUB/Ctrl+Z (EOF marker in some systems)
|
||||||
|
- 0x7F (127) - DEL character
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter()]
|
||||||
|
[string]$WatchFolder = "C:\Dnc_Files\Q",
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[string]$FileFilter = "*.pun",
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[bool]$IncludeSubfolders = $true,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[int[]]$CharactersToRemove = @(255)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Script info
|
||||||
|
$ScriptVersion = "1.0.0"
|
||||||
|
$ScriptName = "eDNC Special Character Fix"
|
||||||
|
|
||||||
|
# Display banner
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " $ScriptName v$ScriptVersion" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Validate watch folder exists
|
||||||
|
if (-not (Test-Path $WatchFolder)) {
|
||||||
|
Write-Host "[ERROR] Watch folder does not exist: $WatchFolder" -ForegroundColor Red
|
||||||
|
Write-Host "Please create the folder or specify a different path." -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display configuration
|
||||||
|
Write-Host "Configuration:" -ForegroundColor Yellow
|
||||||
|
Write-Host " Watch Folder: $WatchFolder"
|
||||||
|
Write-Host " File Filter: $FileFilter"
|
||||||
|
Write-Host " Subfolders: $IncludeSubfolders"
|
||||||
|
Write-Host " Removing bytes: $($CharactersToRemove -join ', ') (0x$($CharactersToRemove | ForEach-Object { '{0:X2}' -f $_ } | Join-String -Separator ', 0x'))"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Watching for files... Press Ctrl+C to stop" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Statistics
|
||||||
|
$script:FilesProcessed = 0
|
||||||
|
$script:BytesRemoved = 0
|
||||||
|
|
||||||
|
# Create file system watcher
|
||||||
|
$watcher = New-Object System.IO.FileSystemWatcher
|
||||||
|
$watcher.Path = $WatchFolder
|
||||||
|
$watcher.Filter = $FileFilter
|
||||||
|
$watcher.IncludeSubdirectories = $IncludeSubfolders
|
||||||
|
$watcher.EnableRaisingEvents = $true
|
||||||
|
|
||||||
|
# Define the cleanup action
|
||||||
|
$action = {
|
||||||
|
$path = $Event.SourceEventArgs.FullPath
|
||||||
|
$changeType = $Event.SourceEventArgs.ChangeType
|
||||||
|
$fileName = Split-Path $path -Leaf
|
||||||
|
|
||||||
|
# Get characters to remove from the outer scope
|
||||||
|
$charsToRemove = $Event.MessageData.CharsToRemove
|
||||||
|
|
||||||
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | $changeType | $fileName" -ForegroundColor White
|
||||||
|
|
||||||
|
# Wait for file to finish writing
|
||||||
|
Start-Sleep -Milliseconds 500
|
||||||
|
|
||||||
|
# Retry logic for locked files
|
||||||
|
$maxRetries = 3
|
||||||
|
$retryCount = 0
|
||||||
|
|
||||||
|
while ($retryCount -lt $maxRetries) {
|
||||||
|
try {
|
||||||
|
# Read file as bytes
|
||||||
|
$bytes = [System.IO.File]::ReadAllBytes($path)
|
||||||
|
$originalCount = $bytes.Count
|
||||||
|
|
||||||
|
# Remove specified bytes
|
||||||
|
$cleaned = $bytes | Where-Object { $_ -notin $charsToRemove }
|
||||||
|
$newCount = $cleaned.Count
|
||||||
|
|
||||||
|
# Only rewrite if we found characters to remove
|
||||||
|
if ($originalCount -ne $newCount) {
|
||||||
|
[System.IO.File]::WriteAllBytes($path, [byte[]]$cleaned)
|
||||||
|
$removed = $originalCount - $newCount
|
||||||
|
Write-Host " [CLEANED] Removed $removed byte(s)" -ForegroundColor Green
|
||||||
|
$script:FilesProcessed++
|
||||||
|
$script:BytesRemoved += $removed
|
||||||
|
} else {
|
||||||
|
Write-Host " [OK] No special characters found" -ForegroundColor Gray
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
catch [System.IO.IOException] {
|
||||||
|
$retryCount++
|
||||||
|
if ($retryCount -lt $maxRetries) {
|
||||||
|
Write-Host " [RETRY] File locked, waiting... ($retryCount/$maxRetries)" -ForegroundColor Yellow
|
||||||
|
Start-Sleep -Milliseconds 1000
|
||||||
|
} else {
|
||||||
|
Write-Host " [ERROR] Could not access file after $maxRetries attempts" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create message data object to pass parameters to the action
|
||||||
|
$messageData = @{
|
||||||
|
CharsToRemove = $CharactersToRemove
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register event handlers
|
||||||
|
$null = Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action -MessageData $messageData
|
||||||
|
$null = Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action -MessageData $messageData
|
||||||
|
|
||||||
|
# Keep script running
|
||||||
|
try {
|
||||||
|
while ($true) {
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
# Cleanup on exit
|
||||||
|
$watcher.EnableRaisingEvents = $false
|
||||||
|
$watcher.Dispose()
|
||||||
|
Get-EventSubscriber | Unregister-Event
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " Session Summary" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " Files Cleaned: $script:FilesProcessed"
|
||||||
|
Write-Host " Bytes Removed: $script:BytesRemoved"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Stopped watching folder" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user