cmiles - info

Life, Tech and Unimportant Minutiae

Created and Updated by Charles on 5/9/2026.

2026 April After Image
2026 April After Image: My home for 23 years - when I started the 2nd store was on Wetmore, hadn't opened that long ago and shared an entrance with Full Cycle - in the 2010s the 2nd store moved north to Oro Valley. So many good years, so many great people and so many happy memories - now just an after image of the sign and some empty fixtures. Charles Miles. 4/6/2026.

I worked on the Summit Hut codebase in some way for about 2 decades before the Summit Hut went out of business in 2025. In the last few years of the business I was the only developer left working on the code. Without the Summit Hut the code itself doesn't have much meaning or value - but one artifact that seems worth preserving as a piece of nostalgia and personal history (and probably amusement/interest for the technologies and details mentioned) here is the final version of my Summit Hut README.md - it was last updated 2/8/2025. I fixed a couple of typos and moved the the 'Thank You' section to the top (in some ways this is the most interesting section and doesn't deserved to be buried at the bottom), otherwise this is a frozen in time version that stands as a reminder of some wonderful times and people!


Thank You!!

If you have made it this far in the ReadMe I owe you a sincere in person Thank You - let's go for a hike!!!

I can't currently tell you how far custom Summit Hut code goes back - but I've seen pictures of Dave Baker with big floppy disks which should give you an idea! By the time I came to the Summit Hut in the early 2000s Dave and Mitch already had a full system written in Delphi that ran the Summit Hut (with earlier software written by Dave Baker and Jim Harsha) - some of which is still running as I write this.

I didn't start on the Dev team and got to watch from the outside as Dave, Mitch and Aaron put us on the path to the .NET Framework and C# in the early 2000s. Major applications from that era included a new Asp.net version of the Summit Hut website (Aaron and Mitch), Web Product Manager (Aaron), GLS (Dave) and Order Manager (Mitch). As you might imagine anyone involved - both users and devs - celebrated some awesome wins and some disappointing failures. In general the current Summit Hut software owes quite a debt to the decision to choose C# and .NET which has allowed our software to continue to evolve!

My first code for the Summit Hut was in VBA - Excel code that created improved Restock Sheets, helped with balances and analyzed sales. Thanks to help from Aaron this code was re-written several times to be better and better and then the spirit of that code made the transition to .NET and ETL style reporting apps. I updated a local reporting db monthly before I had permission to code directly against the database and eventually jumped on the .NET 3 WPF Betas to code what would become Inventory Display and a number of the apps we use today.

While a lot of my learning was done from books, reading, podcasts (.NET Rocks!) and classes it is with deep appreciation that I look back on the incredible inspiration I took from Dave Baker's IMS (and his general approach to understanding and improving the business thru information/reporting and constantly improvement), Aaron Wagner's Web Product Manager and IMS Quick Search (and his deep focus on the users - can't say enough about his incredible help in my early programming endeavors) and Mitch Baker's focus on business value (and his IT setup that continues to serve us well!).

If you talk to me in person I can tell you about all the things I lament about the current state of our code and code base - there will probably always be things to lament with over 20 years of history to reckon with and real world business concerns and constraints involved - and I could write about missed opportunities, mistakes, disagreements, mis-steps and current pain points - all visible in (or between the lines of!) the code I suppose - but more importantly I can tell you a lot about all the great business, good decisions, best efforts and care that went into this code!

It is worth understanding that this code represents many days (and nights!) of great coders doing the best they could for the Summit Hut - on some days it was business, a job and a paycheck and that was the best we could do, but on most days we created code with love, craftmanship and respect for all the amazing people at the Summit Hut. The people at the Summit Hut have always been the highlight, both those who work here now and the many that have passed thru, and some away, over the years... I am proud of the people and jobs that this software has allowed the Summit Hut to support! Sorry for the Problems, Warm Regards and Honest Best Wishes - Charles Miles, 12/5/2021, last update 2/8/2025


ShOne

Welcome to the main repo for 'modern' Summit Hut code!

Much of what you should need for day to day operations is in GitHub, and a large portion of it is in this repo. But we have long tail of legacy software so see GitHub and explore - be careful of historic/archived repos and don't miss ShTimeCapsule for deep historic exploration. Also for true legacy software we should have some on-disk-only historic data that you can ask for access to (likely including the Delphi code/dev environment and Mitch's last SVN repo, including build directories, before that repo died/was shut down).

If you are new to this repo or moving dev machines PLEASE see the Getting Started section below - it tries to list everything you need installed, my experience from setting up new dev machines for myself is that skipping any of this will likely just mean coming back to it later...

Main Ideas:

The core of these were written many years ago, benefitted from many years of work/thought/dev at the Summit Hut and continue to be very relevant! Based on actual real world experiences and outcomes these are not set in stone - this is not a manifesto - but they are a solid place to improve from!

  • Take Maximum Advantage of Tooling - assuming you are on a reasonably capable dev machine Visual Studio+Resharper is happy to show you references, apply refactorings and show you errors from ALL 140+ projects! Forget remembering what else your code change might impact - just have it all in front of you.
  • One Version - different syntax across language versions, library versions across framework versions, constantly changing external libraries and confusing problems referencing one library from another because of versions - all of these things cost painfully valuable time as projects spread out over years and decades of different versions... My hope is that having everything accessible in one solution makes keeping everything at one version possible.
  • Latest Versions - I know that staying on one version is at best a hopeful goal - but in truth I have a more ambitious goal: stay on 'latest'. Yes 100%, every upgrade is a chance for some painful bug - but every update is also a chance that your programs improve with zero effort, for new opportunities emerge and for us to make small changes and stay current rather than getting stuck on an old version (blocking us from other upgrades!) that will be time consuming and confusing to upgrade.
  • Constant Updates - There are only so many resources (especially time) but both software and business processes benefit when software can keep moving forward! Forward progress doesn't have to mean 'the next big-new-thing', it could just be small/quick-to-make changes: adding a shortcut key, coding a new warning, or a new report. With software that is frequently updated there is at least the opportunity to make small/frequent/quick improvements. With stagnant code or might be a half day to figure out which repo, checking it out, make sure the right build tools are installed, find the config file that was missed in the commit a year ago, try to upgrade packages (but instead falling into a mire of version/package conflicts), figure out internal updates, etc...
  • Let Go of Believing You Know - In the 'old days' between number of people, fresh code and operational setup there was a period of time when the best skill may have been knowing who to talk to about some code. Over the years as decisions, software, people and processes have spread out over years, decades, of time there is no one to ask, you just have to read the code, and that holds true even if you wrote the code! The single solution approach puts all the code in front of you - exactly what you need if you can't hold it all in your head.
  • Document, for Everyone! Code as Documentation!! Visible Progress Messages as Documentation!!! Show Technical User Help - DON'T UNDERESTIMATE THE USERS!!!! Pragmatic approaches:
    • Try to use name, patterns and approaches in code that help the code be its own documentation and then add brief notes as needed. Try to avoid descriptions of what the code is obviously doing, instead add context - anyone using this code base will have to read the code, so a pragmatic use of time is not to write perfect-best-practice documentation but instead to leave great hints for a good developer who will be reading the code anyway. As a rule we ALWAYS have copious amounts of context around ...everything...
    • Document for the Users!! As possible add progress message, help and documentation in the GUI to help everyone not only use the programs but understand, troubleshoot and help you help them! Use documentation to try to make EVERYONE part of the Dev Team - when you show you care, take the time to help, make it possible for someone to quickly get something done and constantly improve how we do things it helps connect people to the software and we, you, need the help!!

Of course all that said the real interesting parts are always the grey areas - here are other current repos NOT combined into this solution - and some reasons they are stand seperate:

  • Summit-Hut/DevEnvironmentHelpers: Docs and Tools to help with a Dev/Test environment to work with Summit Hut Code. - Help for Dev/Test setup - kept as a separate project to keep this smaller, simpler and less complicated to potentially check out on a dev server.
  • Summit-Hut/ShImageServiceExternal: An image server targeting Linux designed to be Public Internet Facing. - Targetting linux and sitting outside of our internal network this project is isolated because it should always be designed to run without only SFTP file drops from our internal system.
  • Summit-Hut/ShInventoryExplorer-AndroidUtilityApp: The Summit Hut Mobile Android Utility App - Restock, Pick Lists, etc.. - In use today mainly for the restock and pick list functionality. Hard to communicate how useful the Xamarin Forms tech was at the time but MS has now dropped Xamarin Forms for Maui, but I think it will make sense to migrate this app only when Maui is more mature. This project is isolated because staying with Xamarin Forms locks this app into older framework versions.
  • Summit-Hut/MobileInventoryCollector-WindowsCeApp: Windows CE Inventory Scanning App for the MC-3### WindowsCE Wireless Scanners - We still use some highly durable WindowsCE devices with integrated laser barcode scanners. This requires Visual Studio 2008 and so the software for them is isolated in this project.

Style:

  • Use Entity Framework linq for queries whenever possible - this is controversial and for some queries it is trivial to hand craft sql that will out perform a generated EF query, but currently maintaining code is a much bigger problem than db optimizations so in general using linq and making it very easy to see everywhere a field is used is a huge advantage. Use the existing EF projects rather than creating your own layer.
  • Always use 1ShConfig.xml for configuration values!!! Get database and in-house service connections from the LogAndMail ShConfig or methods like the DbContext .GetInstance() and GeneralData Standard/StringBuyingContextProvider that use this config. THIS IS VERY IMPORTANT and allows you to use an 'override' configuration file to switch to test DBs and Services. 9/1/2023 - this 'system' is not complete with the main offender being the PaymentEngine/Service which currently can not easily be redirected for testing - old programs do not use the XML file of course but you will find strong support for this feature! Most programs and console apps will report what database they are pointing to in the title bar or first few lines of output.
  • Use the ShObfuscationTools and ObscureEnvironmentHelper App to avoid storing sensitive data in the code - look closely at the options, all client machines will not have the Environment Keys distributed so take a second to understand the options. EVERY SERVER and dev machine that is going to run code using the Environment Keys MUST have the keys manually setup - the ObscureEnvironmentHelper App is designed for this and LastPass for the values.
  • Use Seq Logging - something like a customer order will interact with many different systems from when it is placed until it is fulfilled - Seq gives a way to see information for many different systems at once. In addition Seq can be a gateway for motivated non-programmer employees to see what is happening in the system - valuable because they may have much more insight into the actual process than you do and the more eyes on our processes to spot issues and problems the better! Use the logging setups available in LogAndMail - these will default to writing to the Console, a file (either beside the program or in a user's my docs) and writing to Seq for Debug and above. Also consider adding 'hints' into your seq events if you can give next steps, troubleshooting or other information that could help make a log entry (an error most obviously) actionable.
  • PLEASE use and keep the deployment scripts updated even if the Powershell scripting/publishing is not your preference! The scripts give everyone a standard way to publish and if done the same way every time there are massive advantages when looking back on 'what happened' (esp. if it is a years later)...
  • Use the Sh.Config.TaskScheduleBuilder to help create/tear down/update the server tasks and make sure that it either reflects, or is the source of, any Server Task schedule changes. This is the only reasonable way to keep the Tasks in a format where we can update or recreate them in bulk if needed!
  • Try to concentrate complexity in code (this project...) rather than in the Database or Infrastructure. A good example is putting periodic DB clean up tasks in the CheckCleanWarn project rather than as Stored Procedures in the DB - the idea here is that the Summit Hut is currently more likely to have full stack developers/consultants rather than a long term dedicated DB Admin, almost any task will require looking at the code anyway so try to put as much as possible in the codebase...
  • TargetFramework, LangVersion, RuntimeIdentifier and Platforms are set for EVERY project in the Directory.Build.props. - please try to keep this setup as it vastly simplifies dependencies. While more might move to linux in the future for the moment this solution is unapologetically x64 Windows.
  • Latest Office 365 Only - you will see Office 365 listed below as needed for dev - atm we are only supporting Office 365 'latest' desktop apps, no legacy versions. Currently writing/creating excel files is best done thru ClosedXML (refactor away from Interop to create Excel documents) but Interop will be part of this library long term as a way to read data from the active file (ie the data and file the user is looking at on screen).
  • Write ReadMe files and deploy them with the code! We have a historic lack of documentation - one detail that is already very much in progress is to get some high level ReadMe material in place to help someone have a chance diving into the code with some basic useful information. Current ReadMe files are often named 1_[Project]-ReadMe.txt so that they will, in many cases, show up at the 'top' when browsing files sorted by name.
  • Try to stick to DNS for things like the TaskServer and DevServer - we should all learn from the incredible utility that aliasing the DB as db01 in DNS has had in code over the years - as new Servers have been built for updated SqlServer versions it only takes changing DNS and all the clients point to the right place!

Getting Started

You will need:

  • A Capable Windows Dev Machine - ShOne has a large amount of Windows GUI code (WPF and Winforms) and even if you could get everything you needed installed on a Mac/Linux dev box (I don't think you actually can fwiw) you wouldn't be able to test so you really need a Windows dev machine. Maybe not quite 'required' but realistically you are going to need the dev machine to be part of the Summit Hut domain. The ShOne solution has 150+ projects and you will need a 'capable' machine to reasonably work in a solution of that size.
  • Visual Studio - probably the latest (non-preview) version, because there are WPF and WinForm GUI projects my experience is that installing Visual Studio, even if you want to use another IDE, is the easiest way to get everything installed. VS is pretty good these days at installing functionality on the fly but you certainly want ASP.NET and web development (add WCF), .NET desktop development and Data Storage and Processing. I would also recommend selecting Universal Windows Platform Development and selecting recent Windows Development Kits and .NET Multi-Platform App UI development.
  • Office 365 Desktop Apps - These projects use COM Interop with Office and the easiest way to not get errors is to install Office 365 (if you have errors make sure the latest version is installed and manually launch the programs to make sure they are working and don't need a login or other information).
  • Powershell - Scripts expect a 'latest' version rather than the version installed with Windows - skip odd compatibility issues and just install latest... (Also consider installing Windows Terminal and making latest Powershell the default shell)
  • Inno Setup - This is used by the scripts to create packages and must be installed.
  • Git for Windows - git should be available at the command line for scripts
  • Windows SDK - the app deploy scripts use signtool.exe to sign the InnoSetup generated setup files - I believe for the moment that installing a Windows SDK is the easiest way to get this tool installed. You may have to adjust script paths for this - perhaps best to keep an SDK version installed on all dev computers.
  • DevExpress WinForms Subscription - still used in the Promo Editor and Order Manager although try not to create any new usage. It seems the current best way to work with the components is by adding your DevExpress NuGet feed (found at the bottom of the 'Download my Products' page) and pulling/updating packages from there. You should use the unified installer ONLY to install the Reporting Components so that the report designer will work in Visual Studio.
  • Install the Summit Hut Obscure Environment Helper and configure it as needed for the code you are going to work on (may require information from the Summit Hut LastPass) - for client app only work you may not need this
  • A test environment for database and services is HIGHLY advisable, but at present we don't have a formal setup for a test environment - ask a current dev if they have anything setup.

LastPass: In general I have tried to get most of the documentation into the git repos but in some cases (say re-authorizing with Amazon) where 'admin' level credentials are needed there may be documentation in a LastPass entry.

You may want to have the IT-Documentation-Summit-Hut GitHub repo available - without a 'standard' DevOps setup to work with it is inevitable that you will need to understand some of the Summit Hut network to deploy/troubleshoot/understand/work with our system. A domain account goes a log way towards being able to explore some of the internal network - but you might also need to work on various admin access issues and potentially access to at least a subset of our Last Pass setup may be useful.

GUI App installers are signed - this might be considered optional in our current environment and probably could be skipped but currently from a computer on the domain:

  • Manage User Certificates; Personal/Certificates -> right click AllTasks, Request New Certificate, Next, Active Directory Enrollment Policy, Next, Click the link under Sh Code Signing 01, Select Common Name, fill in Summit Hut (with the space), hit Add, Apply, Ok; Check 'Sh Code Signing 01' (if you can't check it out you might not have applied the value in the previous step?) and then Enroll. If you refresh the certmgr you should see a cert issued to Summit Hut by hut-CA under Personal Certificates.
  • (Unfortunately I don't appear to have kept notes on setting up the cert on the server - too bad because I remember that I had to do some troubleshooting to produce a cert that actually worked...)

Very Strongly Suggest:

  • AI Coding Assistant/GitHub Copilot - This spaced is changing very fast right now (2025) but noting this here as a sort of reminder, with a dizzying variety of code/libraries/scripts/etc. I suspect even very experienced Devs will speed themselves up on some part of this code with AI Assistance.
  • Jetbrains Resharper - Optional but atm still adds some strong refactoring and other options not directly available in Visual Studio.
  • https://github.com/warrenbuckley/Compact-Log-Format-Viewer - We currently use Seq heavily but local log files are essential and most programs write them... The logs are readable in a text editor but this is so much better that it is worth knowing installing.
  • WinSCP - this program has both a Windows GUI and a .NET Core package - we do less FTP/SFTP than ever these days but WinSCP has proved to be very flexible and being able to manually try connection options in the GUI and transfer them to the code has been very useful.
  • Smart Command Line Arguments Visual Studio Extension - easier than managing commandline arguments in the json launch files and I don't hesitate to check the related files in so some common arguments might already be available.
  • XAML Styler Visual Studio Extension - XAML will likely be in this code base a long time and it is great to have automatic formatting

Likely Useful and/or Currently Often Used:

  • grepwin - hopefully the monolith ShOneMain solution means you can cntrl-shift-f find most of what you need but scripts and other details mean this is a nice utility to take advantage of.
  • linqPad - plenty of other tools and approaches here but this is a great spot to write/try/experiment with a quick program and is great for some db querying
  • dotnet script - Csx files are increasingly useful although sticking to linqPad and lprun might be a smart way to go...
  • Sql Server Management Studio - linqPad is great but since we run an in-house SqlServer instance SSMS is very useful

YMMV:

  • RegexBuddy - plenty of other tools out there but this has a lot of functionality and has been a long time go to - one pattern these days is create via AI and test and rework in RegexBuddy
  • Postman - there are competitors but it seems like many people still know this program, I've had a good experience using it and we may have a set of helpful calls for Magento
  • Fiddler Classic - for capturing raw calls I find Fiddler Classic useful.
  • greenfish icon editor pro - In general I am looking to minimize time spent on icons and this program has proved simple, easy and reliable
  • Notepad++ - Windows Notepad has improved over the years but this is still worth installing - there are some good plugins available too!
  • BeyondCompare - like that this supports more file formats than some other diff programs I've tried
  • Windows Terminal - should be the windows default I think - set it to open latest Powershell by default
  • AutoHotKey - in a way not important and a bit obscure but the idea is to have a way to be slightly more productive on the keyboard - my fav is mapping some simple arrow key and related movements to caps lock plus right hand home row keys (a tip of the hat to vim)
  • PowerToys - on screen color dropper, ruler, quick launcher and more

Once everything is installed on the commandline run:

  • Tools-InstallGlobalTools - this will get the command line tools the scripts need squared away.
  • Tools-UpdateAllTools - make sure all tools are up to date

1ShConfig.xml - Most - BUT NOT ALL - programs in this repo use 1ShConfig for connection strings and a number of settings that you will want for develepment use. Please take time to read about the file and options in the LogAndMail ReadMe - this will save you some time figuring out where settings come from and easy ways to override them for development.

Dev Environment Tooling - Summit-Hut/DevEnvironmentHelpers - this can make your life a little easier - see the docs there, a few quick notes:

  • Use Sql Server Developer Edition - Sql Server Express will have problems with our DB sizes
  • (Papercut SMTP)[https://github.com/ChangemakerStudios/Papercut-SMTP] is VERY useful - while some emails have moved to MS Graph SMTP will be with us for a long time and this is a great tool
  • See the internal DNS setup - there may be some helpful things already setup
  • Understand 1ShConfig - already mentioned above but very helpful!
  • Consider keeping life simple and naming your dev machine 'devserver' - could be a problem if you have/need multiple devservers but can also save some headache!

Some very random troubleshooting notes:

  • There is a script file to clear all the bin and obj folders - this can be a useful step beyond 'clean'
  • Error NETSDK1112 The runtime pack for Microsoft.NETCore.App.Runtime.win-x64 was not downloaded. Try running a Nuget restore with the RuntimeIdentifier 'win-x64': This error could mean exactly what it says but in my experience this can mean that it is time to delete the bin/obj folders and consider clearing the nuget caches (nuget locals all -clear -> if you run this expect it to take some time for it to re-download...)
  • As mentioned with the error above with 140+ projects I have had very rare problems with cached Nuget packages - this seems worth writing here because the error message I have gotten is never 'Nuget packages have problems - clear the cache' but instead something very unrelated.

Tech, the Future, Musings

Our current stack is a fragmented blend of WPF, Winforms, Console Apps, WCF, dynamic SQL, EF, etc... When possible:

  • Think twice about any new applications or libraries - there is a good chance that what you want to do could have a place in existing applications and/or you could refactor and improve current code and applications.
  • Try hard to migrate to newer solutions like the EF projects and ClosedXML/ReportsTwo - but careful about re-writes or fighting with what already exists - sometimes the best solution might just be a bit more Windows Forms code or tweaking the dynamic SQL!
  • WPF will be viable for MANY years and atm my suggestion is that you lean in and continue to produce WPF where it makes sense. Be very very careful about fragmenting this codebase into too many new GUI technologies that might not stand the test of time or (ie: webtech) may have fast paced life cycle that we don't really have resources to support.
  • Think about maintenance and having to pass your work to someone else - the reality is the Summit Hut still has programs in service first written 2 decades ago, thinking we won't have to maintain code long term or that we will do a 'big project' to replace something in the future is ...dubious...
  • Refactor, Refactor, Refactor! This codebase was consolidated into a single repo after decades of disconnected work - there are huge opportunities to elminate code duplication, improve consistency and lift functionality!

Environment Expectations:

Creating/maintaining/re-building the Summit Hut Network is beyond the scope of this document and the Summit Hut code is built expecting this environment (there is some flexibility but Summit Hut code has NOT been written with moving it to a completely new/different environment as a primary consideration!). But to help developers remember and recognize some key details a few notes are presented here:

  • Windows Server based network with Active Directory, Certificate Authority, specific Users, Security Group and Mailing Lists - all needed/expected, there is no master list and hopefully this never needs to be recreated...
  • Sql Server at db01
  • Seq server
  • SMTP Relay
  • DNS:
    • Speedway (primary physical location) is detected via 10.10.11.xxx and OV (Wetmore! 2nd physical location) is detected as 10.10.13.xxx -> this is hard coded into modern code and either needs to be replicated, updated or a better system found. There is a Config setting that can be used to override the detected location - but it is NOT meant as a way to 'set all locations', it is only meant for testing and maybe special cases. (Note in old Delphi programs you had to manually set the location.)
    • db01 - this has been our long term alias for the db server, don't break this - many many things will need to be reconfigured
    • taskserver - some scripts expect this DNS entry. In 2023 the expectation is internal Tasks, Services and Sites should all be found in the 'hut' folder of the taskserver.
    • devserver - used by some scripts and hopefully setup to be useful for dev
    • transfers02, photos02, giftcards02 - all aliases that need to point to the taskserver
    • inv.hut.local - also needs to point to the task server for the static site for Mobile Inventory Scanner software instructions and distribution
    • payment - points to the payment/paymentengine server, currently Orion
    • seq - should point to the seq server
    • mail01, mail02 - should point to the smtp relay server

Project Overview Notes:

Amazon/02

Amazon is slowing shutting down MWS access in favor of the Selling Partner APIs - newer code is in the 02 folder. Code to push items and stock to Amazon and get orders and reports from Amazon. Console apps for different functions are published as exes, pushed to the Task Server and run with Task Scheduler.

Apps

WPF GUI Apps live here. Recent GUI apps have all been done in WPF with older apps primarily in WinForms (of Delphi for the oldest apps). A huge part of the functionality of these apps is in the WpfParts Library.

ATS

ATS console apps to pull vendor stock into our system for various vendors. Vendor Stock can be used both for Drop Ships and for buying reference. Console apps for different vendors are published as exes, pushed to the Task Server and run with Task Scheduler.

B2B

Largely legacy code but still used primarily in the exchange of B2B POs with several vendors. There is a fascinating history here dating back to Dave and Mitch's involvment in pioneering a free XML based data exchange specification more modern and more free than EDI solutions.

Business Objects

In the mid-2000s long before C# and .NET had anything like a 'standard' data access story Dave Baker wrote a generator to create a data layer with features that he used in GLS. The generation isn't currently supported and this library is currently frozen - but fairly straightforward code means it has come forward into .NET Core.

CheckCleanWarnRunner

A long lived program to run a wide variety of tasks - some general users will call many of the generated emails 'bot' emails and know the program that way - but there are many things here related especially to reporting, checking the database, cleaning up and warning about possible problems

Classic Apps

A bit of a catchall for older apps that are still in use...

Classic Data, UI, Utils

Largely authored by Aaron Jones starting in what was probably the Framework 2.0 era for WPM, an early ASP.net version of Summit Hut and for other apps as well. Even today it has useful functionality but is only kept as a legacy library - code should be updated away from these libraries with the idea one day this goes away.

Clipboard

Support for data to the clipboard (and to help with Drag and Drop to some extent) for GUI Apps

EmailCrm

A system for sending emails from the Summit Hut about orders. This was our primary email system on the old Summit Hut Asp site - now it serves a small number of orders and supports Gift Cards with the majority of emails coming from Magento.

EPPlus

In early 2020 EPPlus released their last 'free' version. EPPlus is a great Excel library and best wishes to them - well worth being a paid project - but EPPlus is a legacy library in this code base with all recent effort going into using ClosedXML - with that in mind a local copy of the last free version is included in the project.

ExcelInterop

Used both for reading from the open application and for writing to Excel in older reporting. For writing to Excel try to use ClosedXML rather than Interop.

GeneralData

Some code here dates all the way back to Linq2Sql and this library has evolved thru time - not all code or approaches are ideal but try to reuse this data layer and when you find problems try to refactor this to make all of the code better. Also a number of services are listed in this repo.

Generated Service References

Contains the generated WCF Service References and some help generating them. This is located in the project but is not in the VS solution.

ItemSearch

Dating back to an origin in Microsoft's late 2000s 'Oslo" effort with MGrammar, MSchema, MGraph and design surface called Quadrant this currently uses a parser called Irony to turn a text item search language into an item search. The success here has been that over the years this has facilitated a number of user searches that are powerful and sometimes slightly free form without allowing/needing the user to understand SQL.

LogAndMail

Common Seq logging setup, basic email functionality and general SH Configuration - try to use this rather than something custom.

M2

Originally written by Mitch Baker starting in 2020 this took his experience with sync to our first Magento site and improved it for our V2 Magento Site. In recent years the code has been migrated to .NET Core and integrated with other projects. This does all things sync with Magento - Inventory, Items, Images, Products...

OrderAutoReceiver

Not quite fitting into other buckets the OrderAutoReceiver has an important function making Drop Ship orders work correct in our system. Originally a service but now deployed to the Task Server.

OrderIntegration

OrderStateUpdate has a number of functions that help the flow of web orders by looking at the state and making changes and updates. The ShipStation integration pulls some shipping information from ShipStation (primarily used for Amazon).

Printing

PO, Tag and Talker output - the PO output is for Excel - Tags and Talkers abstract away dealing with the ZPL used to produce these items.

ReportDates

A library to abstract reporting periods and to help with the construction of more complex sets of periods both in code but also thru somewhat natural language text snippets - '-21d to t', 'March', '2010' are supported along with options for 'x periods back' and previous years (both by date and by day). This library might not be what/how I would write it today but it has stood the test of time and provided awesome flexibility for power users and has some nice code shortcuts.

ReportEngine

An older reporting engine used by some of Dave Baker's code. Legacy, refactor away from this as possible.

Reports

Both an older mostly Excel Interop based reporting and a newer effort both in Excel via ClosedXML and thru writing static/self contained HTML Files. Try to only use ReportsTwo going forward.

Scanner

A well tested library for getting intput from USB HID Scanners - in the future it might be an advantage to use the POS HID libraries that allow more formal capture and communication with the scanners - but this library, for it's intended uses, has been very well tested at this point.

Transaction Processing

Written originally for the ASP.net site (that followed the old Homesite site!) written by Mitch and Aaron this helps with Transaction processing and is still used for Order Manager and some other apps.

WpfParts

The Apps folder (above) derives quite a decent amount of functionality from the WPF components shared in this folder - the idea here is to write windows/controls here and be able to reuse them across applications.


Created by Charles on 8/1/2025. Updated on 5/9/2026.

2026/5/9 Note: I've continued to use and enjoy OSM tagging below in the photos and content that I've been creating. Recently I've had trouble getting data back from public servers (frequently 'Too Many Requests'). It could be me, my code, my IP address or ..., but it is the same workloads and queries that I was running for many months and I'm not sure what has changed. But in any case leaving a note here that wiktorn/Overpass-API: Overpass API docker image makes it quite easy to run your own Overpass API server and that has been a great solution for me.

The Pointless Waymarks GeoTools and Pointless Waymarks CMS have both had the ability to take position information and compare it to GeoJSON reference data to automatically create tags for content, such as photographs, for some time now.

For example, the photo below is tagged with:

arizona,coral bean,coronado national forest,pima county,rincon mountain wilderness,rincon mountains,santa catalina ranger

Of those tags the following were created automatically:

arizona,coronado national forest,pima county,rincon mountain wilderness,rincon mountains,santa catalina ranger district

2024 December Coral Beans
2024 December Coral Beans. Charles Miles. 12/9/2024.

For me, it has been great to have automatic, accurate tagging of land ownership/management, trails and various other geographic minutiae that I care about.

I was on Wheeler Peak in Great Basin National Park earlier this year and took a few photos at sunset. At home, I used the Pointless Waymarks GeoTools to add locations to my photos and then generate tags. The generated tags were helpful, but I was slightly disappointed that my photos from the summit weren't automatically tagged 'wheeler peak' - this led to two improvements.

Buffering Locations

Wheeler Peak and my photo are both represented by a single point. This representation is both completely true and somewhat unhelpful. On the one hand the 'true summit' of Wheeler Peak is a single point - but it doesn't make sense to only tag photos standing exactly on that point 'Wheeler Peak' and almost no one works with equipment that is accurate enough to even reliably identify when you are on the exact point!

2025 August Geo Tools Buffer Setting
2025 August Geo Tools Buffer Setting.

To better match points and lines code has been updated to accept a setting that allows buffering source point and line data. The point for the Wheeler Peak photograph now becomes a circle that covers, and allows matching to, Wheeler Peak.

OSM/Overpass

My experience is that if you are interested in tagging landscape photos no single data source will have everything you are interested in, and some details (local names are a good example) might not be present in any data source. With that in mind, the first version of the Feature Intersect Tags used local GeoJson files (generally an easy format to export geographic data into) and local PAD-US Data data. Two important benefits of this approach:

  • No dependence on online services being up and available
  • Ability to create custom files that combine, exclude and edit data sources into exactly what you want (QGIS may be useful here)`
  • GeoJSON is supported by a variety of tools (geojson.io for example) and with some care can be edited in a text editor

The downside is that you have to collect and curate all the data yourself. This is too much setup for an average user. Even for me this setup worked best for my local area where the time and effort to create curated reference files has a great return on investment.

While there is no perfect source of truth for trails, peaks, rivers and other landscape features OpenStreetMap has an impressive amount of relevant data that is available thru the Overpass API.

Overpass turbo and QGIS+the QuickOSM Plugin are two ways to explore this data and to experiment with the API.

2025 August Geo Tools OSM Overpass Tagging Settings
2025 August Geo Tools OSM Overpass Tagging Settings.

The Pointless Waymarks GeoTools and Pointless Waymarks CMS can now use the settings above to tag the my Wheeler Peak photo with:

great basin national park,nevada,united states,wheeler peak,wheeler peak summit trail,white pine county

2025 July Sunset from Wheeler Peak
2025 July Sunset from Wheeler Peak. Charles Miles. 6/15/2025.
2025 August Geo Tools Results for a Wheeler Peak Photo including OSM Results
2025 August Geo Tools Results for a Wheeler Peak Photo including OSM Results.

Nothings Perfect...

Overall the inclusion of buffering and OSM data has been a nice step forward for tagging in the Pointless Waymarks software - but it isn't without some challenges...

Noise

Buffering is crucial for including all the features you want to generate tags from, but it will inevitably include some that are less valuable. A good example is buffering the track/line from a trail run and generating tags - buffering+OSM data makes it very likely that the names of the trails you ran are returned as tags - great! But it also makes it likely that the names of intersecting trails you ran past are returned as tags... In some cases that is great - it may be useful to look back and see that you ran past a junction, and nice that all adjoining activities come up in a tag search for the run. But here is a more obviously not-useful example - a 55-mile bike ride from 2011 tagged with OSM and my usual settings and files produced these tags:

1st avenue,3rd st bicycle boulevard,ace hardware,alamo wash,albertsons,alvernon optical,alvord road,arcadia wash,arizona,arizona trail,avenida de la potranca,bbva,box canyon,box canyon wash,brandi fenton memorial park,broadway jessica,broadway kolb,broadway langley,broadway northeast,broadway smiles denistry,broadway wilmot,bus 15,bus 17,bus 3,bus 37,bus 7,cactus forest drive,cactus forest trail,calle cipres,calle santo,camino de garanon,camino real,campbell ave,campbell plaza,casa loma condominiums,casa loma estates,casas lindas,centrepark drive,cienega creek pantano wash,cloud ridge,columbus boulevard,conner park,contempo drive,copper star condominiums,craycroft,discovery ridge open space,duffy family community center,eardlina avenue,east 1st street,east 22nd street,east 29th street,east 2nd street,east 3rd street,east 4th street,east 5th street,east 6th street,east 8th street,east 9th street,east acoma place,east adams street,east alandale place,east alberta drive,east arrowhead drive,east avenida del cazador,east baker street,east bellevue street,east blacklidge drive,east broadway boulevard,east bromley street,east buddy lane,east burns street,east calle arizona,east calle de amigos,east calle javelina,east calle ojos verde,east calle villa rica,east camino bacelar,east camino del desierto,east camino del rio,east chauncey street,east citrus avenue,east cloud road,east colette street,east country club vista drive,east croydon park road,east delano street,east desert oak trail,east drexel road,east elida street,east escalante road,east fairmount street,east farness drive,east florence drive,east fort lowell road,east freeman place,east glenn street,east golf links road,east grant road,east graybill drive,east halcyon road,east harborage drive,east hawthorne street,east helen street,east holaway drive,east irvington road,east jeremy crossing road,east joan place,east kenyon drive,east knox drive,east la madera drive,east laguna street,east lazy r ranch road,east lazy ranch road,east lee street,east lester street,east limberlost drive,east linden court,east linden place,east mc millan drive,east mohave road,east monte vista drive,east navajo road,east old spanish terrace,east old spanish trail,east oldooz place,east pantano trail,east pastime road,east peach street,east pima street,east portal airosa,east prince road,east river front drive,east river oak trail,east river road,east roger road,east rosewood street,east saguaro crest place,east seneca street,east shoreline drive,east smoot drive,east south regency circle,east spanish ridge place,east speedway boulevard,east tanque verde lane,east tanque verde road,east thunderhead ranch road,east vactor ranch trail,east waverly street,east wetmore road,east willard street,east wind dancer drive,east wrightstown road,east yavapai road,el dorado,el gheko,entrada,evening mist lane,flap,george mehl family foothills district park,glenn campbell ne,glenn east,handmaker assisted living facilities,hidden glenn,kimberly woods apartments,kingston knolls terrace,la madera,la madera park,lamadera park,liberty tax,life spa,manana vista,mehl foothills park,mesquite grove,miramonte,mountain 1st avenue,mountain avenue,mountain view avenue,nailz,norte corte melodia,north 1st avenue,north alvernon way,north arcadia avenue,north avenida de la vista,north avenida de san ramon,north avenida del cazador,north avenida la vallita,north avenida natachee,north avenida valiente,north bacobi avenue,north beverly avenue,north calle agua verde,north calle de amigos,north calle rosario,north camino arco,north camino blanco,north camino cardenal,north camino castile,north camino de la puerta,north camino de lupo,north camino del celador,north camino del obispo,north camino escuela,north camino gacela,north camino kino,north camino luz,north camino pio decimo,north camino real,north camino rio soleado,north camino seco,north camino sinuoso,north camino sumo,north campana drive,north campbell avenue,north campbell estates,north cherry avenue,north columbus boulevard,north country club road,north craycroft road,north desert avenue,north dodge boulevard,north east plaza drive,north eastgate drive,north edith boulevard,north euclid avenue,north fair oaks avenue,north flagstaff place,north flanwill boulevard,north forgeus avenue,north four winds drive,north hacienda del sol road,north hampton street,north highland avenue,north indian ruins road,north jessica avenue,north kolb road,north langley avenue,north laurel avenue,north leonora avenue,north longfellow avenue,north maguire avenue,north martin avenue,north montego drive,north mountain avenue,north mountain view avenue,north old sabino canyon road,north olsen avenue,north orlando avenue,north palo verde boulevard,north pantano road,north park avenue,north placita vida,north plumer avenue,north pontatoc road,north prudence road,north ralph avenue,north richey boulevard,north rio cancion,north rio verde vista drive,north river gate place,north river hills drive,north river ranch place,north rosemont boulevard,north round rock drive,north sabino canyon road,north san sebastian drive,north santa rosa avenue,north sarnoff drive,north silkie place,north sparkman boulevard,north sutton lane,north swan road,north sycamore avenue,north tanuri drive,north torino avenue,north treat avenue,north tucson boulevard,north tyndall avenue,north venice avenue,north via encantadora,north via entrada,north walnut avenue,north warren avenue,north west plaza drive,north wilmot road,north wilson avenue,north winslow drive,north winstel boulevard,north wyatt drive,old spanish trail,old spanish trail greenway,palo verde park,pantano river park,pantano wash,park avenue,paseo rancho esperanza,pima county,pima street baptist church,placita casa ri,proposed gateway center,reflection vista,rillito river,rillito river park,rillito river path,rincon creek,rincon mountains,rincon valley,rio vista,river rd,river road circle,rob wash,rose hill wash,route 3 6th st wilmot eastbound,route 3 6th st wilmot westbound,sabino canyon,sabino vista circle,saguaro national park,san rafael estates,sandpiper apartments,sauce pizza wine,shaheen estates,south avenida los reyes,south blacksburg avenue,south brown avenue,south calle mesa del oso,south camino seco,south dakota sky court,south desert vista drive,south discovery lane,south ferris drive,south floral ridge way,south freeman road,south gollob road,south harrison road,south houghton road,south mann avenue,south melpomene way,south monument view way,south old spanish trail,south pantano road,south pedregal drive,south placita carrasco,south prudence road,south rainwater lane,south reflection vista place,south rocking k ranch loop,south sarnoff drive,south sherwood village drive,south speckled stone way,south star vista drive,south van buren avenue,south woodstock drive,st phillips plaza,sun tran route 1 glenn swan eastbound,sun tran route 1 glenn swan westbound,sun tran route 103x northwest-downtown express,sun tran route 105x foothills-downtown express,sun tran route 108x broadway-downtown express,sun tran route 109x catalina highway-downtown express,sun tran route 11 alvernon,sun tran route 15 campbell northbound from tucson marketplace,sun tran route 15 campbell southbound to banner umc south campus,sun tran route 17 county club golf links to tohono tadai transit center,sun tran route 17county club golf links to broadway houghton park and ride,sun tran route 201x eastside-aero park express,sun tran route 34 craycroft fort lowell northbound,sun tran route 34 craycroft fort lowell southbound,sun tran route 37 pantano northbound,sun tran route 37 pantano southbound,sun tran route 4 speedway eastbound to golf links at kolb,sun tran route 4 speedway eastbound to houghton at broadway,sun tran route 4 speedway westbound from golf links at kolb,sun tran route 4 speedway westbound from houghton at broadway,sun tran route 5 pima west speedway east bound,sun tran route 5 pima west speedway westbound,sun tran route 6 euclid north 1st avenue northbound,sun tran route 6 euclid north 1st avenue southbound,sun tran route 7 22nd street eastbound,sun tran route 7 22nd street westbound,sun tran route 8 broadway eastbound to houghton at broadway,sun tran route 8 broadway eastbound to udall station,sun tran route 8 broadway westbound from houghton at broadway,sun tran route 8 broadway westbound from udall station,sun tran route 9 grant eastbound,sun tran route 9 grant westbound,sun tran route 9 westbound,tanque verde wash,the loop,thunderhead ranch,treat,ventana cayon wash

I didn't hand check all the results but I suspect that these are all true/accurate - but I'm doubting that anyone, regardless of their approach to tagging, would find this useful. I suppose that the code could try to determine 'most relevant' tags in this circumstance - or maybe the tag set and linestring could be passed to an AI with a prompt for the most useful tags - for now, I've simply added an option in the CMS to tag Line Content without using OSM.

API Limits - API Strategy

In anything other than testing and experimenting it is easy to hit the API limits. It isn't complicated to deal with this - it would have been easier if I had realized it was going to happen from the beginning...

'In' Tagging

Disclaimer: I'm not an expert with the Overpass API so there may be approaches and features I am not aware of!

The best way I found to get the areas that a point is in - National Parks, State, Country, Wilderness Areas - is via an 'in' query to Overpass. This (with some filtering for areas like time zones that you are unlikely to want in your tags) works well for a single point, but there isn't a variation of 'in' where you pass in a linestring or polygon. This creates a puzzle regarding getting good information from Overpass about the various land ownership and management areas that a run or hike passes thru especially since both API Limits and good manners dictate that it isn't reasonable to submit every point from a long GPS track to the API for a query. For now, I'm using a simple algorithm the GitHub Copilot helped me write to get a very limited set of points for a line - probably a good enough solution even though it won't catch everything.


Created and Updated by Charles on 3/30/2025.

After a number of months of continuous operation the Pi Zero 2 Wh running my Vibration Monitor Software dropped offline.

I expected it to come back after power cycling it - it didn't. I then suspected that the MicroSD card had an issue - it wasn't. Flaky power supply? No. Pi killed by the heat? The Tucson summer can be very warm, but not the problem. Bad luck? Not really...

2025 March Corrosion and Rust on an SW-420 Vibration Sensor and Wiring
2025 March Corrosion and Rust on an SW-420 Vibration Sensor and Wiring. Charles Miles. 3/30/2025.

One of the things I love about occasionally trying small Raspberry Pi Projects is that I'm always learning new things! In this case, lacking hardware/sensor experience, I hadn't considered the impact of moisture on the wiring and the vibration sensor. Everything you see from the sensor is quite dry, but even in the desert the buried plastic box this sensor was in has condensation and moisture.

In the short term I just replaced hardware - but now on the todo list is protecting the sensors and doing different wiring that will hopefully let this system live a longer life...

PS - I replaced the Pi Zero 2 Wh with a Pi 3 A+ - I was absolutely blown away by the size of the Pi Zero 2 Wh when I got it - it is certainly the smallest hardware I have ever run C#/.NET code on!! But over time I found the 2.4GHz only Wifi and lack of a full-sized HDMI port (ie easy connection to the monitors I own) were too much of a downside - for me the Pi 3 A+ remains a sweet spot in the Pi line.


Created by Charles on 3/11/2025. Updated on 3/19/2025.

Recently I moved my personal projects to Fossil. The move has been fun and interesting!

I'm newer to Fossil and so far for my reasonably simple use cases the cli + built in website have been an easy to work with combination.

But I miss Fork - a fast and friendly git client for Mac and Windows...

What I miss:

  • Quick view of changed and added files powered by a file watcher so the view is mostly-almost-always up to date
  • Quick view of file diffs
  • Fast mouse-driven selection of files to take actions on - I often want to group a few files into a commit and I find clicking a GUI list of files is faster and easier than using the terminal
  • Dedicated Window - when something is important, like version control, it can be nice to have a dedicated window/app

So with a distinct lack of Fossil tooling out in the world I thought it would be fun to write my own helper program! Goals:

  • Fossil has a nice command line interface - try to work with it rather than hide it
  • Be careful about duplicating views and features already in Fossil's web interface
  • Target frequent operations - I suspect that there is no real time savings over the cli for commands that you run infrequently

After about 4 weeks of personal time effort this is what Pointless Fossil - a Fossil SCM Windows Gui Helper looks like:

2025 March Pointless Fossil Main Window
2025 March Pointless Fossil Main Window.

It is very new but I'm actively using and enjoying it. This is very much a work in progress - not enough time to develop any interesting insights - but a few details that might be of interest are below.

Avalonia UI

Avalonia UI is one of several interesting cross-platform options for building desktop applications with .NET. Pointless Fossil is already the largest program I have ever built with Avalonia and overall it has been a positive experience. It seems to me that vs WPF you gain cross-platform potential and occasional syntax/framework improvements - you lose the large body of online help, there are fewer packages/less code available and there is not a great embedded web view.

Fossil JSON API

Fossil has a JSON API that allows you to retrieve information about the state of a repository - VERY useful!! But in the official binaries the json api is not available... To access the JSON API you will have to compile a custom version of Fossil - there is good documentation available, but this was an unexpected todo on the way to getting a working program!

Reading Standard Output

A requirement for the program was allowing the user to respond if Fossil asked a question on the command line. I hadn't written a similar feature before and I assumed that writing to stdin was going to be the messy part. It turned out that stdin wasn't the problem - many of the questions Fossil asks don't end with a new line and I was surprised by the code needed to read stdout in characters rather than lines! GitHub Copilot was very helpful in working out the details - the start of my code is below, I still can't help but wonder if there is a better/simpler way...

        var buffer = new byte[1024];
        var charBuffer = new char[1024];
        var decoder = Encoding.UTF8.GetDecoder();
        int bytesRead;

        while ((bytesRead = await reader.BaseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
        {
            var charsDecoded = decoder.GetChars(buffer, 0, bytesRead, charBuffer, 0);
            for (var i = 0; i < charsDecoded; i++)

DiffPlex

DiffPlex is Netstandard 1.0+ C# library to generate textual diffs - in addition to the core functionality WinUI, WPF, WinForms and Avalonia (via BAndysc's DiffPlex.Avalonia) controls are available. This MIT licensed library is definitely worth being aware of!


Created by Charles on 1/12/2025. Updated on 3/11/2025.

2025 January GitHub Screenshot
GitHub's front page on 1/12/2025.

Git+GitHub is currently an amazing combination. Git has incredible functionality, tooling and resources - GitHub hosts a huge number of projects, supports everything from individuals to enterprises, stars are currently one of the more notable measures of project popularity and GitHub sponsors can help support developers and projects.

For work, popularity and large collaborative open source projects Git+GitHub are an easy choice - for my personal projects I think it is time to make a change.

Here is what I have noticed about my use for personal projects over the past 5 or so years:

  • 99.9% of my work is as a single developer
  • For personal projects my git use tends to be simple - mostly development on main with an occasional branch
  • I browse code and changes on GitHub and appreciate the ReadMe.md functionality - but haven't made meaningful use of anything else
  • I am not looking for popularity/fame/stars...

And here is why I'm moving to Fossil+Chisel:

  • My current long-shot bet is that my interest in my personal code and projects outlives the current (largely friendly+happy+zero-cost-for-simple-use) incarnation of GitHub.
  • I am not fully convinced that it will be possible, practical or desirable for me to host code online in 10/20/30 years - I'm currently moving to Chisel so that my code is hosted offsite, but long-term Fossil's strong, built-in, website/forge functionality is very, very, attractive.
  • As much as possible I want to support what I love, believe in and care about, even if it is in small ways. Fossil is an interesting, long running, practical and functional developer tool that I want to support. A glance at the GitHub and Fossil homepages may give you a hint about my feelings - I want to be the Fossil homepage, not the GitHub homepage...
  • Fun and learning!

The hedge with all this is that it is easy enough to mirror from Fossil to GitHub these days - so for now I am creating mirrors on GitHub...

2025 January Fossil Screenshot
The front page of the Fossil project on 1/12/2025.

If you end up trying Chisel I think one common workflow is to import an existing Git repo - I'm not the person you want to ask about the best way to do this but basically I would point you to:

  • Fossil: Import And Export: Basics on importing and exporting.
  • How to push Fossil local repository to remote hosting - Stack Overflow: The answer with 10 steps is a good description of the workflow I used - BUT at least in Q1 2025 it looks like the key to getting this work is in the Flint bug report below.
  • Override project code - NOT working: Flint/Chisel currently has a bug where the 'Create Repository' screen gives you a critical and very helpful data entry field titled 'Override project code (Optional, but may be needed if pushing an already created repo to Chisel.)' - but it doesn't work. The workaround in the link is pretty simple, but maybe not when you are trying to figure out 'everything'.

Related Links and Notes:

My current public repos on Chisel:


Created and Updated by Charles on 1/20/2025.

The Pointless Waymarks Cloud Backup and Pointless Waymarks PowerShell Runner have been running happily on my main computer for a bit without me thinking about them.

2025 January Pointless Waymarks Cloud Backup Main Window before LiveCharts2
2025 January Pointless Waymarks Cloud Backup Main Window before LiveCharts2.
2025 January Power Shell Runner Job List before LiveCharts2
2025 January Power Shell Runner Job List before LiveCharts2.

I was glad that the programs had been doing their job - but I was disappointed that I couldn't verify they had done their job more quickly. The data about runs needed a better presentation - enter LiveCharts2 (on GitHub): "Simple, flexible, interactive & powerful charts, maps and gauges for .Net, LiveCharts2 can now practically run everywhere Maui, Uno Platform, Blazor-wasm, WPF, WinForms, Xamarin, Avalonia, WinUI, UWP."

The LiveCharts2 site site has galleries, code and documentation that make it quick to add simple charts. The charts are fairly new, so I'm still testing/working, but I'm happy with the first round of results!

2025 January Pointless Waymarks Cloud Backup Job List with Active Upload
2025 January Pointless Waymarks Cloud Backup Job List with Active Upload.
2025 January Pointless Waymarks PowerShell Runner Job List
2025 January Pointless Waymarks PowerShell Runner Job List.

Posts Before:
2025 January Pointless Waymarks Cloud Backup Main Window before LiveCharts2
2025 January Photo Content Page Details Block - Before Update
2024 December Pointless Waymarks Feed Reader Feed Editor with Auto Mark Options
2024 December Pi Sliced Day Photos Solstice to Solstice Sunsets Video Cover Image
2024 December CMS Photo Direction Display