<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
        <channel>
                <title></title>
                <description>Personal homepage and blog for Nate Shoffner.</description>
                <link>https://nateshoffner.com</link>
                <atom:link href="https://nateshoffner.com/feed.xml" rel="self" type="application/rss+xml" />
                
                        <item>
                                <title>Elasticon 2024</title>
                                <description>&lt;p&gt;This is a bit of a retroactive post that’s been sitting in my drafts, but two months ago I had the pleasure of attending ElasticON 2024 in New York City thanks to our company being a partner and sponsor for the event. It was a great experience and I learned a lot about current and upcoming features within the Elastic stack. I also had the opportunity to meet some of the Elastic team as well as some of my clients.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/PXL_20241113_233131090.jpg&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/PXL_20241113_233131090.jpg&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conference was held at the Manhattan Center, a beautiful venue in Midtown Manhattan. The trip was spread out over two days, with the first day being dedicated to keynote sessions and the second day being dedicated to workshops. GenAI was a big focus at the conference, with most of the events being centered around it in some form or another, whether it’d be RAG (Retrieval Augmented Generation) applications or getting into the nitty-gritty of the underlying technology with things like &lt;a href=&quot;https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch&quot;&gt;BBQ (Better Binary Quantization)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/PXL_20241113_191904550.jpg&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/PXL_20241113_191904550.jpg&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of my favorite events was the Geospatial lightning talk where it covered building out a RAG service leveraging textual and vector data with geospatial data.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/PXL_20241113_181603461.jpg&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/PXL_20241113_181603461.jpg&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another one of my favorites was the security presentation going over &lt;a href=&quot;https://www.elastic.co/guide/en/security/current/attack-discovery.html&quot;&gt;Attack Discovery&lt;/a&gt;, which illustrated a really cool feature of mapping out the relationship of security events to the MITRE ATT&amp;amp;CK framework.&lt;/p&gt;

&lt;p&gt;The following day, we attended the Elastic office where we were able to both attend and lead workshops for GenAI certification.&lt;/p&gt;

&lt;p&gt;Least but not least, it wouldn’t be a conference without a swag haul picture.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/PXL_20241116_010716075.jpg&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/PXL_20241116_010716075.jpg&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, it was a great experience and would definitely recommend attending ElasticON if you have the opportunity.&lt;/p&gt;
</description>
                                <pubDate>Tue, 28 Jan 2025 04:00:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2025/01/elasticon-2024/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2025/01/elasticon-2024/</guid>
                        </item>
                
                        <item>
                                <title>RRTA ModeShift Reverse-Engineering</title>
                                <description>&lt;p&gt;A few years ago, the &lt;a href=&quot;https://www.redrosetransit.com/&quot;&gt;RRTA&lt;/a&gt; (Red Rose Transit Authority) performed a big overhaul to their transit system, including the introduction of a new mobile app called RRTA Go Mobile by &lt;a href=&quot;https://www.modeshift.com/&quot;&gt;ModeShift&lt;/a&gt;. The app was designed to replace the old paper tickets and passes with a digital system that could be used to purchase passes and plan trips. As a big proponent of public transit, this was a very welcomed improvement for me. There were a few issues early on with QR codes not scanning properly and/or failing to renew, but those issues were quickly resolved. I myself have submitted a ticket or two to the developers regarding some issues I’ve encountered and received a fairly timely response with fixes following shortly after, so props to the developers for that.&lt;/p&gt;

&lt;p&gt;RRTA also offers another app/web interface called &lt;a href=&quot;https://busfinder.redrosetransit.com/InfoPoint/&quot;&gt;BusFinder&lt;/a&gt; operating on the &lt;a href=&quot;https://availtec.com/mystop/&quot;&gt;myStop&lt;/a&gt; system by &lt;a href=&quot;https://availtec.com/myavail/&quot;&gt;Avail Tech&lt;/a&gt;, which allows you to track buses in real-time, a feature ModeShift sadly fails to offer. This effectively requires riders to utilize multiple apps for basic functionality and RRTA doesn’t seem to advertise the BusFinder app very well, as I’ve met many riders who were unaware of its existence.&lt;/p&gt;

&lt;p&gt;Earlier this year, I decided to take a look at the BusFinder system and see if I could reverse-engineer it to create my own tools for tracking and analytics. I was able to get a basic prototype working, which was pretty simple considering it’s a pretty basic REST API and eventually released a &lt;a href=&quot;https://github.com/NateShoffner/python-rrta&quot;&gt;Python wrapper&lt;/a&gt; for it.&lt;/p&gt;

&lt;p&gt;I was curious if I could do the same with ModeShift, but I quickly discovered that it was a bit more complicated than BusFinder. The ModeShift app is a hybrid app, meaning it’s essentially a web app wrapped in a native app. This is a pretty common practice for mobile apps, as it allows developers to write a single codebase for multiple platforms, but it also makes it a bit more difficult to reverse-engineer.&lt;/p&gt;

&lt;p&gt;I started by decoding the APK using &lt;a href=&quot;https://ibotpeaches.github.io/Apktool/&quot;&gt;apktool&lt;/a&gt;. Next I replaced the &lt;a href=&quot;https://developer.android.com/privacy-and-security/security-config&quot;&gt;Network Security Configuration&lt;/a&gt; to allow user-installed certificates, which is required to intercept HTTPS traffic. The source code for the app was then modified to disable any various &lt;a href=&quot;https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning#what-is-pinning&quot;&gt;certificate pinning&lt;/a&gt; methods and to allow the use of a custom CA certificate. After that, the modified APK was recompiled with Apktool, signed with my own key via &lt;a href=&quot;https://github.com/patrickfav/uber-apk-signer&quot;&gt;uber-apk-signer&lt;/a&gt;, and installed on my device.&lt;/p&gt;

&lt;p&gt;I then used &lt;a href=&quot;https://www.telerik.com/download/fiddler-everywhere&quot;&gt;Fiddler Everywhere&lt;/a&gt; to act as a man-in-the-middle (MITM) proxy to intercept the HTTPS traffic from the app. There are plenty of free/open source alternatives to Fiddler, but I’ve found Fiddler to be the most user-friendly and wanted to try the Everywhere version, as I’ve been a long-time user of the original Fiddler for Windows.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/modeshift-fiddler.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/modeshift-fiddler.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m not particularly interested in any of the authenticated endpoints, so I’m only going to focus on the unauthenticated endpoints for now since they’re the most useful and allow stuff like trip planning. Admittedly, these endpoints do a lot of the heavy lifting as far as actual routing and trip planning goes. I was initially assuming that ModeShift was piggybacking off the same system as BusFinder (they perhaps are, to a degree), but it seems that ModeShift is doing a lot of the heavy lifting itself, rather than passing off the routing to something like Routes API from Google or something similar.&lt;/p&gt;

&lt;p&gt;My plan is to offer a client implementation for ModeShift within the &lt;a href=&quot;https://github.com/NateShoffner/python-rrta&quot;&gt;python-rrta&lt;/a&gt; package. My hope is to create more tools for RRTA riders to utilize and to hopefully encourage more ridership.&lt;/p&gt;
</description>
                                <pubDate>Thu, 28 Dec 2023 18:00:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2023/12/rrta-modeshift-reversing/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2023/12/rrta-modeshift-reversing/</guid>
                        </item>
                
                        <item>
                                <title>LCWC and Dispatch Rabbit Holes</title>
                                <description>&lt;p&gt;Earlier this year, I became interested in the LCWC (Lancaster County-Wide Communications) incident page - a county-wide dispatch system that provides incident updates for all of Lancaster County, PA.&lt;/p&gt;

&lt;p&gt;It’s very useful for residents to know what’s going on with regards to various emergency services incidents. It’s not without its flaws, however. For starters, downtime seems to be a big issue especially during peak incident periods which is less than ideal considering that’s when most people are going to be slamming the site. Additionally, there doesn’t seem to be any sort of historical data. I wanted to atttempt to resolve those issues and also add some of my own, such as real-time notification systems and integrations with various social media platforms. This is where the rabbit hole begins.&lt;/p&gt;

&lt;h4 id=&quot;method-1---web-scraping&quot;&gt;Method #1 - Web Scraping&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/medical_incidents.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/medical_incidents.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Initially, my goal was to simply scrape the web page itself, provided it was accessible considering the aforementioned frequent downtime. The downtime issue becomes even more apparent when you start polling it regularly, even at off-peak times. There was also another major issue with scraping - the lack of a static identifier for incidents. All incident details are subject to change except for the date/time (as far as I’ve been able to decern) but considering the lack of granularity with incident timestamps, there’s nothing to prevent a conflict.&lt;/p&gt;

&lt;h4 id=&quot;method-2---rss-feed&quot;&gt;Method #2 - RSS Feed&lt;/h4&gt;

&lt;p&gt;Next I decided to look into the available RSS feed. Saviour of all our issues with no drawbacks whatsoever (foreshadowing is a literary device in which a writer gives an advance hint of what is to come later in the story). The RSS feed appears to be cached with a reasonably low TTL and doesn’t seem subject to the pitfalls of the limited Drupal execution resources for the rest of the site. Additionally, it offers a GUID for each incident, which, while purely an RSS feed relic, does help us individualize incidents. Not all that glitters is gold however. The RSS feed is missing a critical component: incident categories. Unlike the webpage, the feed provides no indication of whether an incident is tagged as Fire, Medical, or Traffic. To resolve this, we essentially need a way to extrapolate what category an incident is based off of things like incident description and the units assigned, if there any even are. This requires us to have reliable references for each of the properties what they’re correlated with, certainly doable with a fair degree of accuracy, but that requires a lot of data to use as a reference and still isn’t 100% accurate.&lt;/p&gt;

&lt;p&gt;An example RSS feed item:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;MEDICAL EMERGENCY&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&amp;gt;&lt;/span&gt;http://www.lcwc911.us/lcwc/lcwc/publiccad.asp&lt;span class=&quot;nt&quot;&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;WEST COCALICO TOWNSHIP; SWAMP CHURCH RD &lt;span class=&quot;err&quot;&gt;&amp;amp;&lt;/span&gt; GALEN HALL RD; PENDING; &lt;span class=&quot;nt&quot;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;pubDate&amp;gt;&lt;/span&gt;Mon, 06 Nov 2023 13:35:26 GMT&lt;span class=&quot;nt&quot;&gt;&amp;lt;/pubDate&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;guid&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;isPermaLink=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;d0fc384b-9468-4907-bfc5-e444864f5597&lt;span class=&quot;nt&quot;&gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;method-3---esri-arcgis&quot;&gt;Method #3 - ESRI ArcGIS&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/lcwc_incident_map.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/lcwc_incident_map.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Around this time I realized there was more data out there, just in another format: the live incident map. It featured much more in-depth data on incidents that I’ve been able to access so far including incident numbers (which resolves the static identifier issue), priority codes, longitude/latitude, and agency. This was especially helpful because I was having to do my own geocoding based off of intersection/municipality which didn’t necessarily indicate the exact coordinates of the incident and was especially troublesome if some of that data was missing form the incident listing, effectively making that impossible. The live map is based on an ESRI ArcGIS service which luckily provides a REST API, although it’s not as straightforward as I would’ve liked when it comes to real-time information. This was my first foray into ESRI so everything was a learning experience.&lt;/p&gt;

&lt;p&gt;Initially I thought it’d be as simple as just providing some geospatial coordinates for the county to get all the active incidents within those bounds, provided courtesy of the county GIS department (albeit in a different specification, but nice nonetheless). The first hurdle I ran into was actually requesting the incident data. Since the data is intended to be used in “layers” on the live map, each incident category has it’s own endpoint and (as far as I know) no way to just lump them into a single request. So if we want Fire and Medical incidents, we have to make 2 separate requests. The second hurdle came from dealing with the caching mechanism ESRI utilizes. This makes sense when you’re dealing with scalability and users commonly requesting the same data via the map interface, which is generally going to consist of relatively predictable geospatial coordinates. To bypass this, I initially added a bit of random “jitter” to the geospatial data - just enough to be (hopefully) unique, but not enough to impact the return dataset. This actually worked very well until I realized that the caching mechanism wasn’t just based on known parameters, but ALL parameters. So the easier/more reliable method became appending the timestamp to each request. Gotta love the pre-mature over-engineering.&lt;/p&gt;

&lt;p&gt;So now with this ESRI method everything should be good right? Nonsense. There’s one small, but glaring issue: unit names. Both the web interface and RSS feed use fully-qualified unit names and the ESRI system uses a shorthand form for unit names. For identification sake, this isn’t a big deal but the shorthand names aren’t exactly intuitive for people, so a mapping system will likely need to be created to correlate the two such as MED865 to MEDIC 86-5. Some of them are intuitive, others are not.&lt;/p&gt;

&lt;h4 id=&quot;remaining-issues&quot;&gt;Remaining Issues&lt;/h4&gt;

&lt;p&gt;Given the nature of how emergency response services work, there is some overlap with out-of-county units being dispatched to incidents if they’re close to the incident at hand. This is a problem if we want to be able to identify what agency is handling said unit and we have no reliable way of doing so without knowing the other county’s unit naming scheme and basically going through this whole process with neighbouring counties, which is a more than just a bit out of scope for this project.&lt;/p&gt;

&lt;p&gt;I’ve basically opted to use the ESRI data as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Single_source_of_truth&quot;&gt;source of truth&lt;/a&gt; as it’s the most comprehensive with incident details. However, it does not seem to track stuff like transfers and standby statuses, as well as out-of-county incidents.&lt;/p&gt;

&lt;h3 id=&quot;future-plans&quot;&gt;Future Plans&lt;/h3&gt;

&lt;p&gt;Living in the city, I’m rather accustomed to the sound of sirens whirring by. It’s nice to know what might be going on around me or for family/friends that are high risk for medical emergencies. So I set out to create a proximity-based notification system for incidents in my area/around my family/friends. But first we need the data. Naturally there’s no API handy so we get to do this ye old fashioned way.&lt;/p&gt;

&lt;p&gt;I’ve been accumulating a lot of data. All the scraping functionality has been shoved into a Python package on PyPi for anybody to use. There is a REST API for querying active and historical incidents, as well as agency information. There is also a webhook service that will fire off updates to a Cloudflare Worker which formats the data into compatible formats for a variety of platforms such as Discord, Slack, Twitter, and more. If there’s interest or boredom sets in one day, I might implement a websocket interface for real-time updates.&lt;/p&gt;

&lt;p&gt;Privately, I’ve set up a notification service for both myself and friends/family so that if an incident occurs within a specified radius of their address, I will be notified. This has proven to be almost scarily accurate as not long ago I got a notification that there was a fire at my location yet I heard no alarms within my building. Looking outside, I saw a multiple fire response units at the building directly across the street from me. Perhaps a bit more granularity is needed.&lt;/p&gt;

&lt;h4 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;/h4&gt;

&lt;p&gt;What started as a little weekend project turned into me deep-diving into a lot of different technologies and learning a lot of new things. I’ve learned a lot about ESRI and ArcGIS, which is a very powerful platform. I’ve also learned a lot about the county’s emergency response system and how it works. A number of helpful people who work in the field have been kind enough to answer my questions and provide insight and empathize with their frustration with the current system. Throughout this I’ve learned that there is no real sense of standardization between county-level dispatch.&lt;/p&gt;

&lt;p&gt;I’ll probably continue to work on this project here and there and play with some data visualization like heatmaps and such. I’m also considering adding a feature to allow users to subscribe to incidents within a specified radius of an address, but that’s for another day.&lt;/p&gt;

&lt;p&gt;The API itself is open source, so technically anybody could host an instance, but I’d recommend just using the centralized instance when possible to avoid hammering the county’s/ESRI’s servers any more than necessary.&lt;/p&gt;

&lt;p&gt;Example REST API response:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;6ac7e52c-977c-47aa-8654-c0daadf4c0b5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;category&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Medical&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MEDICAL EMERGENCY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;intersection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;S PRINCE ST / W FARNUM ST&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;municipality&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LANCASTER CITY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dispatched_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T03:55:12+00:00&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2309013581&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;priority&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;agency&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LANCASTER EMS (LEMSA)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;coordinates&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;latitude&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;40.03403523000003&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;longitude&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;-76.30727306399996&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;meta&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;added_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:10.661851&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;updated_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:24.051156&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;resolved_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;client&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ArcGISClient v0.9.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;automatically_resolved&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;units&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;664422e6-4593-4ba6-9bd3-2bb5626bdad5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;short_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;INT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;added_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:24.095154&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;removed_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_seen&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:24.095154&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;automatically_removed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;823cdbdb-c15b-41f3-9015-55e7dc5ae1d6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;short_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MED&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;added_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:24.096157&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;removed_at&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_seen&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2023-09-12T04:04:24.096157&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;automatically_removed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can find the Python parser package on &lt;a href=&quot;https://pypi.org/project/lcwc/&quot;&gt;PyPi&lt;/a&gt; as well as on &lt;a href=&quot;https://github.com/nateshoffner/python-lcwc&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The API itself is also open source and can be found on &lt;a href=&quot;https://github.com/nateshoffner/lcwc-api&quot;&gt;GitHub&lt;/a&gt; as well and is additionally available on &lt;a href=&quot;https://hub.docker.com/repository/docker/nateshoffner/lcwc-api&quot;&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
</description>
                                <pubDate>Tue, 07 Nov 2023 19:06:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2023/11/lcwc-and-dispatch-rabbit-holes/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2023/11/lcwc-and-dispatch-rabbit-holes/</guid>
                        </item>
                
                        <item>
                                <title>Google Play Developer Account Termination</title>
                                <description>&lt;p&gt;Recently I had the pleasure of dealing with Google’s heavy handed approach to over-sweeping account terminations.&lt;/p&gt;

&lt;p&gt;On September 11th, I received the following email from Google out of the blue:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is a notification that your Google Play Publisher account has been terminated.&lt;/p&gt;

  &lt;p&gt;REASON FOR TERMINATION: Prior violations of the &lt;a href=&quot;https://play.google.com/about/developer-content-policy.html&quot;&gt;Developer Program Policies&lt;/a&gt; and &lt;a href=&quot;http://www.android.com/us/developer-distribution-agreement.html&quot;&gt;Developer Distribution Agreement&lt;/a&gt; by this or associated accounts as outlined in previous emails sent to the registered email address(es) of the Publisher account(s).&lt;/p&gt;

  &lt;p&gt;Google Play Publisher suspensions are associated with developers, and may span multiple account registrations and related Google services.&lt;/p&gt;

  &lt;p&gt;You can visit the &lt;a href=&quot;https://play.google.com/about/enforcement.html#enforcement-process&quot;&gt;Developer Policy Center&lt;/a&gt; to better understand how we enforce Developer Program Policies. If you’ve reviewed the policy and feel this termination may have been in error, please reach out to our &lt;a href=&quot;https://support.google.com/googleplay/android-developer/contact/emailappeals?t=7187132&amp;amp;ts=BOT&amp;amp;email=$%7BEMAIL_ADDRESS%7D&amp;amp;n=$%7BDEV_NAME%7D&quot;&gt;policy support team&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Do not attempt to register a new developer account. We will not be restoring your account at this time.&lt;/p&gt;

  &lt;p&gt;The Google Play Team&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I received no warnings prior to the termination email I received nor did I have any idea as to why the account was terminated to begin with. The only email I ever received regarding this account was on August 29th, 2018 where I was notified that an app was removed from Google Play because of a Children’s Online Privacy Protection Act (COPPA) compliance requirement, which I adhered to and the app was reinstated shortly thereafter.&lt;/p&gt;

&lt;p&gt;I submitted my appeal, explaining I had never received any warnings or occurrences prior to termination and gave some basic information regarding my packages that would be pertinent to a potential occurrence (e.g., content ratings, open-source, embedded ads).&lt;/p&gt;

&lt;p&gt;Additionally, I decided to &lt;a href=&quot;https://www.reddit.com/r/androiddev/comments/d30gqw/account_terminated_without_prior_warning/&quot;&gt;post&lt;/a&gt; over on &lt;a href=&quot;https://www.reddit.com/r/androiddev/&quot;&gt;/r/androiddev&lt;/a&gt; about the situation and found out I wasn’t alone and there was apparently some sort of ban wave, all of which seemed to have a similar story: no prior occurrences, no warning email, and the claim of “prior occurrences” given as the reason for termination.&lt;/p&gt;

&lt;p&gt;The following day after submitting my appeal, I received a response:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Hi Nate,&lt;/p&gt;

  &lt;p&gt;Thanks for contacting the Google Play Team.&lt;/p&gt;

  &lt;p&gt;After further review, we’ve accepted your appeal and reinstated your account. You’ll need to sign in to your &lt;a href=&quot;https://play.google.com/apps/publish/&quot;&gt;Play Console&lt;/a&gt; to modify and/or republish any reinstated apps to make them available on Google Play.&lt;/p&gt;

  &lt;p&gt;If the option to resubmit is not available, please try making a small change to your app’s Store Listing page. For example, you can add and remove a space at the end of your app description.&lt;/p&gt;

  &lt;p&gt;Please let me know if you have any other questions.&lt;/p&gt;

  &lt;p&gt;Regards,
Samantha 
The Google Play Team&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Several other developers I’ve talked to have received the same response with no reasons given for their termination. Any Play Store listings had to be re-submitted but that aside, re-instatetment was seamless.&lt;/p&gt;

&lt;p&gt;I responded to the reinstatement email requesting further information on whey the account was terminated and what steps I could possibly take to avoid future potential issues.&lt;/p&gt;

&lt;p&gt;Then on September 13th, I received a follow up email:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Hi Nate Shoffner,&lt;/p&gt;

  &lt;p&gt;On September 11, 2019, an error resulted in the unintentional ban of your developer account. We apologize for this error and assure you that it will not negatively impact your account standing. We will restore all of your app(s) to their prior state as of September 11, 2019. No action is needed on your part. We expect the restoration process to be complete by September 14, 2019.&lt;/p&gt;

  &lt;p&gt;Your restored app(s) may be reviewed by the Google Play Team, so please ensure that your app(s) are compliant with all &lt;a href=&quot;https://play.google.com/about/developer-content-policy/&quot;&gt;Developer Program Policies&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;If you have any questions or concerns about this process, feel free to &lt;a href=&quot;https://support.google.com/googleplay/android-developer/contact/appwarning&quot;&gt;submit a request here&lt;/a&gt; and we’ll do our best to respond within 1 business day.&lt;/p&gt;

  &lt;p&gt;Thank you for your understanding and for being a valued part of the Google Play ecosystem.&lt;/p&gt;

  &lt;p&gt;The Google Play Team&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, today on September 16th I received a response to me asking for further details as to why the account was terminated to begin withL:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Hi Nate,&lt;/p&gt;

  &lt;p&gt;Thanks again for reaching out. I believe an email was sent out to you (ticket# REDACTED) last Friday explaining the issue.&lt;/p&gt;

  &lt;p&gt;Please refer to the aforementioned email for more information and if you have any further questions please let me know.&lt;/p&gt;

  &lt;p&gt;Regards,
Samantha 
The Google Play Team&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anybody who’s had to deal with monolithic companies like Google knows how daunting it can be when something like this happens. You feel powerless because getting in contact with an actual human seems nearly impossible. What’s worse is that, from what I’ve read, any accounts associated with a terminated account is subject to termination as well. This can cause a massive domino effect when you have several accounts working for one client/company and one of them is terminated.&lt;/p&gt;

&lt;p&gt;Google needs to work on their transparency when it comes to their “valued” members of the Google Play ecosystem. While there is definitely a case to be made for Google needing to do maintenance for malicious apps and developers, even through automated means, there needs to be a more transparent and communicative method of dealing with them in the case of false positives. When an individual’s career and livelihood can but cut off without a warning, it’s a surefire way to get people to abandon your platform for one with better insurance.&lt;/p&gt;
</description>
                                <pubDate>Mon, 16 Sep 2019 20:10:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2019/09/google-play-developer-account-termination/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2019/09/google-play-developer-account-termination/</guid>
                        </item>
                
                        <item>
                                <title>Disable Nvidia Telemetry 1.1</title>
                                <description>&lt;p&gt;Pushed out a small update to for the Nvidia Telemetry tool with a few new features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added: Installer and portable builds&lt;/li&gt;
  &lt;li&gt;Added: Update checking&lt;/li&gt;
  &lt;li&gt;Added: Task Scheduler options&lt;/li&gt;
  &lt;li&gt;Added: File and event logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/DisableNvidiaTelemetry1.1.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/DisableNvidiaTelemetry1.1.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As per usual, you can view the source code over at &lt;a href=&quot;https://github.com/NateShoffner/Disable-Nvidia-Telemetry/&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;download&quot;&gt;Download&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/NateShoffner/Disable-Nvidia-Telemetry/releases/download/1.1/Disable.Nvidia.Telemetry.1.1.0.16.Portable.exe&quot;&gt;Portable (Self-Extracting Archive)&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/NateShoffner/Disable-Nvidia-Telemetry/releases/download/1.1/Disable.Nvidia.Telemetry.1.1.0.16.Setup.exe&quot;&gt;Installer&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
                                <pubDate>Sat, 26 Aug 2017 08:13:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2017/08/disable-nvidia-telemetry-1-1/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2017/08/disable-nvidia-telemetry-1-1/</guid>
                        </item>
                
                        <item>
                                <title>Intel Core i7-7700K Delidding</title>
                                <description>&lt;p&gt;For years, dating back to the Athlon line, I had been using AMD processors for my builds and had been waiting in anticipation for Ryzen’s release, which debuted in February of this year. I had been using an overclocked FX-8350 for a few years, which meant there was no upgrade path in sight that didn’t require a full architecture and socket change, whether that be AMD or Intel.&lt;/p&gt;

&lt;p&gt;In the end, I eventually decided to go the Intel route with the i7-7700K, valuing the additional gaming performance over Ryzen’s multi-threaded capabilities - ones I wouldn’t realistically take advantage of on a day to day basis. Simultaneously, I also decided to order a delidding kit and the necessary supplies to delid the i7-7700K.&lt;/p&gt;

&lt;h4 id=&quot;what-is-delidding&quot;&gt;What is Delidding?&lt;/h4&gt;

&lt;p&gt;Dating back to around Haswell, Intel’s processors have been notorious for reaching extremely high temperatures, especially while overclocking. The leading issue for this seems to be due to the TIM (thermal interface material) they’re using on the die. “Delidding” is the process of removing the Integrated Heat Spreader (IHS) from a CPU with the intention of applying aftermarket TIM to the CPU. It’s unlikely that they’re merely skimping out and using ill-suited TIM, but rather focusing on longevity at stock/moderate voltages. With that in mind, it’s possible that aftermarket TIM solutions may require additional delidding at some point to re-apply fresh TIM, but that’s purely my speculation.&lt;/p&gt;

&lt;p&gt;This isn’t going to act as in in-depth overclocking/delidding guide, there are more than enough of those already throughout the internet.&lt;/p&gt;

&lt;h4 id=&quot;build-specs&quot;&gt;Build Specs&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;CPU: &lt;a href=&quot;https://www.amazon.com/gp/product/B01MXSI216?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Intel Core i7-7700K&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Cooler: &lt;a href=&quot;https://www.amazon.com/gp/product/B019955RNQ?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Corsair H115i Liquid Cooler&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mobo: &lt;a href=&quot;https://www.amazon.com/gp/product/B01NBHXSP6?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;ASUS ROG MAXIMUS IX HERO&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAM: &lt;a href=&quot;https://www.amazon.com/gp/product/B06XRG59PK?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Corsair Vengeance 32GB RGB LED (4x8GB) DDR4 3000 MHZ&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;PSU: &lt;a href=&quot;https://www.amazon.com/gp/product/B00EB7UITQ?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Corsair RM750&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;benchmarks-and-stress-tests&quot;&gt;Benchmarks and Stress Tests:&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;x264 (16 threads)&lt;/li&gt;
  &lt;li&gt;Prime 95 27.9&lt;/li&gt;
  &lt;li&gt;ROG RealBench&lt;/li&gt;
  &lt;li&gt;AIDA64&lt;/li&gt;
  &lt;li&gt;Cinebench R15&lt;/li&gt;
  &lt;li&gt;Vegas PRO 14 (~5m Sony AVC 1080p60 render)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prior to delidding, I was able to overlock to 5.0GHz @1.36v using an AVX offset of -2 and load-line calibration (LLC) set to 3. Even with the offset, AVX workloads resulted in the package hitting 100C temps and instantly shutting down. 4.9GHz @1.35v resulted in much more stability, but not by much in regards to thermals, which were still exceeding 94C and over in the long term.&lt;/p&gt;

&lt;h4 id=&quot;delidding-materials&quot;&gt;Delidding Materials:&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B01MXSI216?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Intel Core i7-7700K&lt;/a&gt; (or whatever LGA 1155/1150/1151 CPU you have)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://rockitcool.myshopify.com/products/rockit-88&quot;&gt;Rockit 88&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://rockitcool.myshopify.com/products/re-lid-kit&quot;&gt;Re-Lid Kit - 1150 / 1151&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B01A9KIGSI?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Thermal Grizzly Conductonaut&lt;/a&gt; (&lt;a href=&quot;https://www.amazon.com/gp/product/B0039RY3MM?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Coollaboratory Liquid Ultra&lt;/a&gt; also works)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/gp/product/B003TP2TBQ?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;Loctite Super Glue - Gel Control&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;91% Isopropyl alcohol&lt;/li&gt;
  &lt;li&gt;Coffee Filters&lt;/li&gt;
  &lt;li&gt;Cotton Swabs&lt;/li&gt;
  &lt;li&gt;Scotch Tape&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternatively, you could you use a &lt;a href=&quot;https://www.amazon.com/gp/product/B0002UEN1A?tag=nate.shoffner-20&quot; target=&quot;_blank&quot;&gt;silicon-based gasket maker&lt;/a&gt; instead of the super glue, either one is easy enough to de-lid and does the job. Just note that the gasket maker will take much longer to cure, hence why I chose the super glue.&lt;/p&gt;

&lt;div class=&quot;project-images-container&quot;&gt;	

        &lt;a href=&quot;/assets/images/posts/7700KDelid1.jpg&quot; class=&quot;fancybox&quot; rel=&quot;delid&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/7700KDelid1.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/7700KDelid2.jpg&quot; class=&quot;fancybox&quot; rel=&quot;delid&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/7700KDelid2.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/7700KDelid3.jpg&quot; class=&quot;fancybox&quot; rel=&quot;delid&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/7700KDelid3.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Using the Rockit88, I popped the IHS off the wafer and removed the old TIM and sealant. Just to be safe, I masked the CPU with tape prior to applying the new TIM, as the liquid metal is &lt;em&gt;extremely&lt;/em&gt; runny, almost like liquid mercury.&lt;/p&gt;

&lt;p&gt;Using the relid kit, I aligned the IHS back above the CPU and applied a drop of superglue on the bottom corners of the IHS and pressed it down. After allowing it to cure for 2 hours, I popped the CPU out of the kit, threw it in the socket and started it up. Almost immediately I noticed a huge difference in thermals. Under both AVX and non-AVX loads, I was barely hitting 72C which is simply mind blowing. With that headroom, I was able to bump up the voltage back to 1.36V and hit that sweet 5.0GHz&lt;/p&gt;

&lt;p&gt;As of posting this, everything has been running stable for a few weeks now and thermals haven’t changed nor have there been any signs of instabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/cpuz.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/cpuz.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;conclusion-and-disclaimer&quot;&gt;Conclusion and Disclaimer&lt;/h4&gt;

&lt;p&gt;Overall, the delidding process is pretty simple and safe if done properly. If you’re on the fence about delidding and plan on overclocking or have started but are exceeding safe thermals, I’d definitely recommend it.&lt;/p&gt;

&lt;p&gt;Just be aware of the risk you’re tasking when delidding your CPU is it will instantly void your warranty. Generally speaking, I’d say it’s a fairly easy process if you’re patient and do it properly.&lt;/p&gt;
</description>
                                <pubDate>Thu, 01 Jun 2017 17:16:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2017/06/intel-core-i7-7700k-delidding/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2017/06/intel-core-i7-7700k-delidding/</guid>
                        </item>
                
                        <item>
                                <title>Disable Nvidia Telemetry</title>
                                <description>&lt;p&gt;Back in early November, Nvidia started bundling telemetry services with their drivers. Gamers Nexus did an &lt;a href=&quot;http://www.gamersnexus.net/industry/2672-geforce-experience-data-transfer-analysis&quot;&gt;analysis&lt;/a&gt; where they inspected data transactions via Wireshark. Their focus seemed to be moreso on dispelling the rumors of personally identifiable information being sent &lt;strong&gt;unencrypted&lt;/strong&gt;, as they didn’t decrypt any of the encrypted traffic. Their results yielded from an hour of testing that nothing was being sent, the services were seemingly dormant.&lt;/p&gt;

&lt;p&gt;For me, however, it’s a moot point. Nvidia should’ve been upfront about the telemetry with their users and I’m not really a fan of unnecessary services running on my computer, so naturally I disabled the services from their inception. I soon found out that they were being reactivated upon updates, which resulted in me throwing together a small utility to handle the disabling work for me.&lt;/p&gt;

&lt;div class=&quot;project-images-container&quot;&gt;	

        &lt;a href=&quot;/assets/images/posts/NvidiaTelemetry1.png&quot; class=&quot;fancybox&quot; rel=&quot;screenshots&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/NvidiaTelemetry1.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/NvidiaTelemetry2.png&quot; class=&quot;fancybox&quot; rel=&quot;screenshots&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/NvidiaTelemetry2.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/NvidiaTelemetry3.png&quot; class=&quot;fancybox&quot; rel=&quot;screenshots&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/NvidiaTelemetry3.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;I’ve shared it with a few people and figured I might as well throw it online.&lt;/p&gt;

&lt;p&gt;Note: I use a small subset of GeForce Experience’s features, including ShadowPlay and have experienced no problems. I can’t speak for every use case and how disabling these services might be impactful in the future, so use it at your own risk.&lt;/p&gt;

&lt;p&gt;You can download the utility &lt;a href=&quot;https://github.com/NateShoffner/Disable-Nvidia-Telemetry/releases&quot;&gt;here&lt;/a&gt; as well as find the source code on &lt;a href=&quot;https://github.com/NateShoffner/Disable-Nvidia-Telemetry&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
                                <pubDate>Fri, 12 May 2017 20:13:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2017/05/disable-nvidia-telemetry/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2017/05/disable-nvidia-telemetry/</guid>
                        </item>
                
                        <item>
                                <title>Seachem Doser 1.2</title>
                                <description>&lt;p&gt;Seachem Doser 1.2 is now available on the &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.nateshoffner.seachemdoser&quot;&gt;Play Store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Major changes include metric support, new products (see below), and an interface redesign with improved material design.&lt;/p&gt;

&lt;p&gt;Previously, I was having to resort to reverse-engineering Seachem’s Flash-based dosage calculators in order to obtain dosage calculations. Thankfully, they finally added web-based &lt;a href=&quot;http://seachem.com/calculators.php&quot;&gt;dose calculators&lt;/a&gt;, albeit with some errors/miscalculations on their end at the time of writing this.&lt;/p&gt;

&lt;p&gt;Additionally, support for Honeycomb and below has been dropped due to insignificant user distribution and the effort required to provide backwards compatibility. Sorry for the few of you that this may affect.&lt;/p&gt;

&lt;p&gt;Full changelog:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added: Discontinued products toggle&lt;/li&gt;
  &lt;li&gt;Added: Dosage copying&lt;/li&gt;
  &lt;li&gt;Added: Seachem warnings&lt;/li&gt;
  &lt;li&gt;Added: Seachem-recommended parameter values&lt;/li&gt;
  &lt;li&gt;Added: Pinnable products&lt;/li&gt;
  &lt;li&gt;Added: Light/Dark theme selection&lt;/li&gt;
  &lt;li&gt;Added: Flourite Sand&lt;/li&gt;
  &lt;li&gt;Added: Flourish Trace&lt;/li&gt;
  &lt;li&gt;Added: Reef Fusion 1 &amp;amp; 2&lt;/li&gt;
  &lt;li&gt;Added: Small (3.5 kg) gravel/sand bag dosage&lt;/li&gt;
  &lt;li&gt;Added: Metric/imperial settings&lt;/li&gt;
  &lt;li&gt;Added: Default product settings&lt;/li&gt;
  &lt;li&gt;Fixed Reef Advantage Calcium dosage&lt;/li&gt;
  &lt;li&gt;Fixed: Gray Coast calculation&lt;/li&gt;
  &lt;li&gt;Fixed: Meridian name typo&lt;/li&gt;
  &lt;li&gt;Fixed: Full-screen keyboard on landscape orientation&lt;/li&gt;
  &lt;li&gt;Changed: All gravel values now round up to next bag(s)&lt;/li&gt;
  &lt;li&gt;Changed: UI redesign (w/ improved material design)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;tablet&quot;&gt;Tablet:&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/SeachemDoser1.2-Tablet.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/SeachemDoser1.2-Tablet.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;phone&quot;&gt;Phone:&lt;/h4&gt;

&lt;div class=&quot;project-images-container&quot;&gt;	

        &lt;a href=&quot;/assets/images/posts/SeachemDoser1.2-Phone1.png&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/SeachemDoser1.2-Phone1.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/SeachemDoser1.2-Phone2.png&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/SeachemDoser1.2-Phone2.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

&lt;/div&gt;

</description>
                                <pubDate>Mon, 07 Nov 2016 21:03:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2016/11/seachem-doser-1-2/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2016/11/seachem-doser-1-2/</guid>
                        </item>
                
                        <item>
                                <title>Moved to GitHub Pages &amp;amp; Site Redesign</title>
                                <description>&lt;p&gt;I’ve just finished moving my website over from WordPress to GitHub Pages. It’s something I’ve been meaning to do for a while now. Despite using WordPress for years, I’ve found it to be rather excessive for my personal needs as far as resource usage and maintenece goes.&lt;/p&gt;

&lt;p&gt;Although I never personally had any security issues with WordPress, it’s definitely a high-profile target and switching to static content definitely helps mitigate some attack vectors. Not to mention the inherent load time decrease because of said static content.&lt;/p&gt;

&lt;p&gt;Having already used Jekyll/GitHub Pages many times before, the move wasn’t terribly painful. There were a few ‘gotchas’ here and there, but with a little hacking, things were ironed out. I’ll probably post some of those solutions in later posts.&lt;/p&gt;

&lt;p&gt;I took advantage of the migration to redesign the site and perform some general maintenece on posts and the like.&lt;/p&gt;

&lt;p&gt;Additionally, all comments have been moved to Disqus.&lt;/p&gt;

&lt;p&gt;There may still be a few quirks here and there that I haven’t noticed yet, but overall things are working smoothly.&lt;/p&gt;
</description>
                                <pubDate>Fri, 11 Mar 2016 19:41:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2016/03/moved-to-github-pages-site-redesign/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2016/03/moved-to-github-pages-site-redesign/</guid>
                        </item>
                
                        <item>
                                <title>Seachem Doser 1.1</title>
                                <description>&lt;p&gt;So I’m about 8 months late to posting this. Granted, I’m quite behind on posting a lot of developments (sleep deprivation puns). Anyway, Seachem Doser is an Android app that I developed a while ago that serves as a “dosage/quantity calculator” for various products Seachem offers.&lt;/p&gt;

&lt;p&gt;Seachem, for those who don’t know/have lives, is a company that offers various products geared towards maintaining freshwater and marine aquariums. Personally, I use a lot of their products for my high-tech planted aquariums.&lt;/p&gt;

&lt;p&gt;They offer calculators on their site that allow you to calculate how much you should dose specific fertilizers, buffers, conditioners, the amount of gravel needed per a specific volume, etc. Sadly, these calculators are all Flash-based. So I decided to make one that’s a bit more flexible. I should note that all of the values for these calculations were pulled from their official calculators, after a bit of reverse-engineering. At first I just made a Windows-based calculator/library that you can find on &lt;a href=&quot;https://github.com/NateShoffner/Seachem&quot;&gt;GitHub&lt;/a&gt;. Eventually the issue of convenience took hold and I decided to make it mobile.&lt;/p&gt;

&lt;p&gt;As of today, I just updated it to work on tablets and polished things up a bit since I had some free time.&lt;/p&gt;

&lt;p&gt;As with the Windows version, the Android version is also open source on &lt;a href=&quot;https://github.com/NateShoffner/Seachem-Doser&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you happen to be somebody who will find it useful, feel free to download it through the &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.nateshoffner.seachemdoser&quot;&gt;Play Store&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;tablet&quot;&gt;Tablet&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/SeachemDoser1.1-Tablet.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/SeachemDoser1.1-Tablet.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;phone&quot;&gt;Phone:&lt;/h4&gt;

&lt;div class=&quot;project-images-container&quot;&gt;	

        &lt;a href=&quot;/assets/images/posts/SeachemDoser1.1-Phone1.png&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/SeachemDoser1.1-Phone1.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/SeachemDoser1.1-Phone2.png&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/SeachemDoser1.1-Phone2.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

&lt;/div&gt;

</description>
                                <pubDate>Wed, 23 Dec 2015 21:35:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2015/12/seachem-doser-1-1/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2015/12/seachem-doser-1-1/</guid>
                        </item>
                
                        <item>
                                <title>Dropbox Does Not Access Files Throughout Your PC</title>
                                <description>&lt;p&gt;Recently, there has been an &lt;a href=&quot;http://www.e-siber.com/guvenlik/dropbox-accesses-all-the-files-in-your-pc-not-just-sync-folder-and-steals-everything/&quot;&gt;article&lt;/a&gt; circulating around with a pretty damning accusation. To summarize the post, they claim Dropbox is transferring data on the entire computer, not just folders that are designated to be synced.&lt;/p&gt;

&lt;p&gt;This is clearly a bold accusation, with seemingly little evidence to back it.  This speculation is based entirely on filesystem events and unverified network traffic..yep.&lt;/p&gt;

&lt;p&gt;At the time of writing this, the author has not disclosed what “unnamed DLP agent” software he is using nor has he provided any real evidence to support his claims.&lt;/p&gt;

&lt;p&gt;Let’s explain the filesystem activity:&lt;/p&gt;

&lt;p&gt;Just to run a simple test, I’ll be using &lt;a href=&quot;https://technet.microsoft.com/en-us/library/bb896645.aspx&quot;&gt;Process Monitor&lt;/a&gt; and setting basic filters to check Explorer and Dropbox filesystem events.&lt;/p&gt;

&lt;p&gt;After creating a new file outside of my designated Dropbox directory, you can see it fires filesystem events to query the file. In particular, &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ff567047%28VS.85%29.aspx&quot;&gt;QueryDirectory&lt;/a&gt; operations which involve &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/aa364980%28v=vs.85%29.aspx&quot;&gt;checking the file path&lt;/a&gt; to see if it belongs to a synced directory.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/DropboxQueryOperations.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/DropboxQueryOperations.png&quot; align=&quot;left&quot; alt=&quot;Dropbox Query Operation&quot; title=&quot;Dropbox Query Operation&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d expect another culprit to the the shell integration. Personally, I don’t use the sync indicators myself, as I have other programs that use shell integration and it can cause conflicts. However, I’d imagine that the shell integration in Explorer requires the files/directories to be queried as well to check for sync status.&lt;/p&gt;

&lt;p&gt;As for the network activity…the author has not even bothered to check the length of the data and compared it to the suspected files nor has he compared the timestamps between the two. Keep in mind that network activity from a program such as Dropbox is perfectly normal, how else would it be able to sync things in realtime?&lt;/p&gt;

&lt;p&gt;So no, based off the limited (see: hardly any) “evidence” provided by the original author, it does not appear that Dropbox is transferring data outside of the designated dirctories.&lt;/p&gt;
</description>
                                <pubDate>Tue, 03 Mar 2015 17:05:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2015/03/dropbox-does-not-access-files-throughout-your-pc/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2015/03/dropbox-does-not-access-files-throughout-your-pc/</guid>
                        </item>
                
                        <item>
                                <title>&quot;Pretend You&apos;re Xyzzy&quot; Server Setup and Build Instructions</title>
                                <description>&lt;p&gt;“Pretend You’re Xyzzy” is a Cards Against Humanity clone that allows you to play online with others. It consists of a Tomcat/JSP server and web page clients.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/xyzzy.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/xyzzy.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the time of writing this, the main server located at &lt;a href=&quot;http://pretendyoure.xyz/&quot;&gt;pretendyoure.xyz&lt;/a&gt; appears to be down, so I decided to set up my own server for a group of friends and myself to play. Initially, there didn’t seem to be much info on setting up the server. The &lt;a href=&quot;https://github.com/ajanata/PretendYoureXyzzy&quot;&gt;GitHub&lt;/a&gt; had a very brief explanation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This project has only been tested in Tomcat 7 and is known to not work in Tomcat 6 without some finagling. Currently, the only automated way to build is is using the Eclipse project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While the setup isn’t terribly complicated or anything, I figured I’d post some instructions on how to set things up since a lot of people seem to be having issues doing so and there don’t seem to be any concise instructions on how to do so.&lt;/p&gt;

&lt;p&gt;These instructions are for a Debian-based installation, but are easily applicable to other distros/platforms as well.&lt;/p&gt;

&lt;p&gt;First you’ll need Apache Tomcat 7 and you’ll want to install the admin panel as well:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install tomcat7 tomcat7-admin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, stop the Tomcat server for the time being so we can modify some permissions:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service tomcat7 stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we’ll edit the users config so we can administrate the server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo nano /etc/tomcat7/tomcat-users.xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add the following line in between the &lt;tomcat-users&gt; and &lt;/tomcat-users&gt; tags, replacing ‘admin’ and ‘password’ with your own secure credentials:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;user username=&quot;admin&quot; password=&quot;password&quot; roles=&quot;manager-gui,admin-gui&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Start the service back up:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service tomcat7 start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we want to install PostgreSQL for our database:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install postgresql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Change over to the postgres user (already set up via the installation process):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo -i -u postgres
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, run the following, replacing ‘password’ with a secure password of your choice:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;createdb cahdb
psql template1
CREATE USER cah WITH PASSWORD &apos;password&apos;;
GRANT ALL PRIVILEGES ON DATABASE &quot;cahdb&quot; to cah;
\q
exit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we need to download the cards database and import it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget https://raw.githubusercontent.com/ajanata/PretendYoureXyzzy/master/cah_cards.sql
psql -h localhost -d cahdb -U cah -f cah_cards.sql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now navigate to http://your_host:8080/manager/html and login.&lt;/p&gt;

&lt;p&gt;From here, you can upload your WAR file and deploy it.&lt;/p&gt;

&lt;p&gt;If your server does not seem to be loading/seems to be stalling, a possible reason could be Tomcat using a blocking entropy source for session IDs. To implement a non-blocking (and slightly less secure) entropy source, open/create a setenv.sh script in /usr/share/tomcat7/bin and add the following line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;JAVA_OPTS=&quot; $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom &quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Save and restart Tomcat.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service tomcat7 restart
Finally, you can access the app via http://your_host:8080/cah.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can download a pre-built/zipped version of cah.war &lt;a href=&quot;/assets/files/cah.zip&quot;&gt;here&lt;/a&gt;. The PostgreSQL parameters are as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Username: cah
Password: password
Database: cahdb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Since this version uses insecure/public credentials, make sure to take necessary precautions to secure your server.&lt;/p&gt;

&lt;p&gt;If you’d prefer to build your own version, follow the instructions below.&lt;/p&gt;

&lt;p&gt;Building the .war file is fairly straightforward. Just download the source from Github via Git or just use the zip functionality.&lt;/p&gt;

&lt;p&gt;You will need the &lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html&quot;&gt;JRE v7u75&lt;/a&gt; installed.&lt;/p&gt;

&lt;p&gt;Open &lt;a href=&quot;https://eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/keplersr2&quot;&gt;Eclipse (Java EE)&lt;/a&gt; and open the project.&lt;/p&gt;

&lt;p&gt;Install Luna if you don’t already have it buy going to Help-&amp;gt;Install New Software. Choose “Luna”. Select “Web, Xml, Java EE and OSGi Enterprise Development”, install it and restart.&lt;/p&gt;

&lt;p&gt;Set Tomcat 7 as your runtime environment server.&lt;/p&gt;

&lt;p&gt;Make sure your build path uses the correct runtime environment as well.&lt;/p&gt;

&lt;p&gt;Database credentials can be changed in the hibernate.cfg.xml file.&lt;/p&gt;

&lt;p&gt;When all is well, you can go to File-&amp;gt;Export-&amp;gt;Web-&amp;gt;WAR File.&lt;/p&gt;

&lt;p&gt;You can upload and deploy that file through the Tomcat admin panel and you’re good to go!&lt;/p&gt;
</description>
                                <pubDate>Sun, 15 Feb 2015 18:12:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2015/02/pretend-youre-xyzzy-server-setup-and-build-instructions/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2015/02/pretend-youre-xyzzy-server-setup-and-build-instructions/</guid>
                        </item>
                
                        <item>
                                <title>Programming - Paradigms, Satire, and Precedents</title>
                                <description>&lt;p&gt;I’m not normally one to get absorbed into drama or gossip on the internet, but this evening I found myself a bit agitated, but not for the reason you might initially assume.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/cplusequality.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/cplusequality.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;introducing-c&quot;&gt;Introducing C+=&lt;/h4&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C+= (pronounced either C-plus-Equality, or See Equality) is a feminist programming language, created to smash the toxic Patriarchy that is inherent in and that permeates all current computer programming languages. Inspired by the &amp;lt;a href=&quot;http://www.hastac.org/blogs/ari-schlesinger/2013/11/26/feminism-and-programming-languages&quot; target=&quot;_blank&quot;&amp;gt;ground-breaking feminist research of Arielle Schlesinger&amp;lt;/a&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C+= was created by the &lt;a href=&quot;http://feministsoftwarefoundation.org/&quot;&gt;Feminist Software Foundation&lt;/a&gt;, whose language philosophy entails the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. The language is to be strictly interpreted using feminist theory. Under no circumstances should the language be compiled, as compilation and the use of a compiler imposes an oppressive and toxic relationship between the high-level descriptive language and the low-level machine code that does all the labo(u)r. Instead, C+= is interpreted, which fosters communication, itself a strong female trait.


2. No constants or persistence. Rigidity is masculine; the feminine is fluid. I.e., fluid mechanics is hard for men &apos;because it deals with &quot;feminine&quot; fluids in contrast to &quot;masculine&quot; rigid mechanics&apos;.

3. No state. The State is The Man. &apos;Nuff said. Hence, the language should be purely functional.

4. Women are better than men with natural language. Hence, the language should be English-based like HyperCard/LiveCode.

5. No class hierarchy or other stigmata of OOP (objectification-oriented programming). In fact, as an intersectional acknowledgement of Class Struggle our language will have no classes at all.

6. On the off chance that objects do mysteriously manifest, there should be no object inheritance, as inheritance is a tool of the Patriarchy. Instead, there will be object reparations.

7. Societal influences have made men often focus on the exterior appearances of women. This poisons our society and renders relationships to be shallow, chauvinistic, and debases our standards of beauty. To combat that, C+= is to tackle only audio and text I/O, and never graphics.

8. Unicode is the preferred character encoding due to its enabling the diverse aesthetic experiences and functionality that is beyond ASCII. UTF-8 is the encoding of choice for C+=.

9. Women are more social than men. Hence, social coding should be the only option. The code only runs if it is in a public repo.

10. Instead of &quot;running&quot; a program, which implies thin privilege and pressure to &quot;work out&quot;, programs are &quot;given birth&quot;. After birth, a program rolls for a 40% chance of executing literally as the code is written, 40% of being &quot;psychoanalytically incompatible&quot;, and 40% of executing by a metaphorical epistemology the order of the functions found in main().

11. Programs are never to be [&quot;forked&quot;](https://en.wikipedia.org/wiki/Fork_(system_call)), as the word has clear misogynistic tendencies and is deeply problematic. Instead, programmers may never demand &quot;forking&quot;, but ask for the program to voluntarily give permission. &quot;Forking&quot; will henceforth be called &quot;consenting&quot;, and it is entirely up to the program to decide if the consent stands valid, regardless of the progress of the system clock.

12. Forced program termination is not allowed unless the program consents to it. The process is part of the choice of the program, not the programmer.

13. Licensing: the Feminist Software Foundation License.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is some example FizzBuzz code written in C+=:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#consider &amp;lt;FEMINIST_RAGE.Xir&amp;gt;;

// TODO replace main() as Progrym entry point; &quot;structured
// programming&quot; is classist oppression
// TODO2: main() is now womain()

// NB one does not argue with C+= Progryms; one makes requests, which
// the Progrym is free to consider or ignore as she pleases
xe womain (xe RequestCount, strong *RequestList[]) {
// NB typically patriarchal fizzbuzz enshrines socially
// constructed limits as immutable fact; here we expose this
// subtle mental tyranny for what it truly is

xe ArbitraryBeginning accepts(present(-50));
xe ArbitraryEnd accepts(present(50));

// naturally, everything revolves around this
xe ThePlaceBetween accepts(present(0));

among(ThePlaceBetween accepts(ArbitraryBeginning),
      ThePlaceBetween honors(ArbitraryEnd),
      ThePlaceBetween improvesBy(present(1))) {
    check(ThePlaceBetween envelops(present(3))) {
        yell(present(&quot;Fizz&quot;));
    }
    recheck(ThePlaceBetween envelops(present(5))) {
        yell(present(&quot;Buzz&quot;));
    }
    unpack {
        // strength &amp;amp;amp; independence!
        yell(present(ThePlaceBetween));
    };

    yell(present(&quot;\n&quot;));
};
present(Satisfaction); };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By now, I hope you would realize that this is in fact satirical. Personally, I found the whole thing quite humorous and well-constructed in regards to the amount of effort and detail put into it, code examples and all. Now I know what you’re thinking. “Gee, how will satire mocking feminism be perceived on the internet?”. This is where things get interesting…&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/cplusequality-cloudflare.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/cplusequality-cloudflare.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project was initially hosted on &lt;a href=&quot;https://github.com/FeministSoftwareFoundation/C-plus-Equality&quot;&gt;Github&lt;/a&gt;, that is until Github decided to pull it due to harassment complaints. Who was being harassed? Nobody. At least not by the project owners. It seems that there were various people, namely feminists, who were being impersonated and had commits to the project being sent under their fraudulent identities. Maybe I’m missing something, but it seems just a &lt;strong&gt;tad&lt;/strong&gt; bit excessive to close the entire repository for an incident caused by a few select individuals who didn’t even own the repository. The project eventually moved to &lt;a href=&quot;https://bitbucket.org/FeministSoftwareFoundation/c-plus-equality&quot;&gt;BitBucket&lt;/a&gt; and the &lt;a href=&quot;https://bitbucket.org/site/master/issue/8629/harassing-repository&quot;&gt;complaints&lt;/a&gt; soon followed, just as baseless and shallow as before. There were even individuals trying to get the domain dropped by CloudFlare. It became quite apparent that these people were acting on emotion and not any sort of actual logic. Naturally, as with any ethical “debate”, there is a astounding amount of hypocrisy and generalizations that just point out the inconsistencies (or possible similarities) between the two parties.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/cplusequality-generalizations.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/cplusequality-generalizations.png&quot; class=&quot;img-fluid post-image center-block&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some people lack the ability to separate a difference of opinion and actual harassment. Pointing fingers at the wrong people (the repository owner) just makes it worse. Just because you don’t agree with the project ethically is no excuse for blatant censorship, it doesn’t matter how to try to spin it. If you do succeed with censoring the other party, you should be aware of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Streisand_effect&quot;&gt;Streisand effect&lt;/a&gt;. This becomes even more crucial when you consider that the project was spawned out of 4chan.&lt;/p&gt;

&lt;p&gt;Overall, I am quite disappointed in Github for the way that they handled (or mishandled rather) this situation. In an attempt to save face, they jumped the gun and quite possibly set a precedent for similar situations in the future. A repo owner should not have to do background checks on each individuals wanting to commit. The entire situation is a result of hypersensitivity and some people’s inability to take into consideration that their outlash could have real world effects. An incident involving &lt;a href=&quot;https://github.com/joyent/libuv/pull/1015&quot;&gt;gendered pronouns&lt;/a&gt; a few weeks back was depressingly similar.&lt;/p&gt;

&lt;p&gt;It’s quite obvious that this project is misogynistic, satirical or not, but that’s not the problem I have with it. My issue with this whole situation is the blatant censorship and corrosive mindset of “I don’t like this, take it down” that constantly plagues the internet. People need to learn to value free speech over their own ideals, otherwise we’re looking at a very bleak future. Attempting to censor those with different opinions will only promote chilling effects, encourage polarization of those involved, and further degrade any sense of intelligent discussion there may be.&lt;/p&gt;

&lt;p&gt;As of writing this, BitBucket has not removed the repository. Jesse Yowell from Atlassian has stated:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;We are aware of this and it is currently being reviewed by our legal team.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hopefully they will properly think this through, not just for public relations sake, but for the long-term effects it could pose. It’d be a shame to see them make the same mistake as Github.&lt;/p&gt;

&lt;p&gt;C+= Sources:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://feministsoftwarefoundation.org/&quot;&gt;Homepage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://bitbucket.org/FeministSoftwareFoundation/c-plus-equality&quot;&gt;BitBucket Repo&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;update-12152013&quot;&gt;Update 12/15/2013&lt;/h4&gt;
&lt;p&gt;Erik van Zijst of Atlassian has &lt;a href=&quot;https://bitbucket.org/site/master/issue/8629/harassing-repository#comment-7363170&quot;&gt;stated&lt;/a&gt; that they will not be removing the repo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;We have no intentions to censor at this point.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;update-12192013&quot;&gt;Update 12/19/2013&lt;/h4&gt;
&lt;p&gt;Contradicting the previous statement, the repo has been removed (along with forks, both public and private). Scott Farquhar has &lt;a href=&quot;https://bitbucket.org/site/master/issue/8629/harassing-repository#comment-7416620&quot;&gt;commented&lt;/a&gt; stating:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;After further consideration, we have decided to remove this repository. While our End User Agreement explicitly prohibits the posting of content that is &quot;racially or ethnically offensive,&quot; we believe it is consistent with the spirit of our agreement to also prohibit content that is offensive toward a specific gender. We will update our End User Agreement to make this prohibition more explicit.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great job, updating your end user agreement for the sake of saving face.&lt;/p&gt;

</description>
                                <pubDate>Sat, 14 Dec 2013 12:28:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/12/programming-paradigms-satire-and-precedents/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/12/programming-paradigms-satire-and-precedents/</guid>
                        </item>
                
                        <item>
                                <title>Programming as an Essential Skill Set</title>
                                <description>&lt;p&gt;Lately, the internet has been abuzz with the recent “Hour of Code” campaign. For those unaware, this is a campaign that aims to introduce people (largely children), to the world of programming in order to “jump-start their futures”. The campaign features well-renowned programmers such as Ashton Kutcher, Shakira, and Barack Obama. Now I’m not attempting make light of Obama’s apparent &lt;a href=&quot;http://www.youtube.com/watch?v=k4RRi_ntQc8&quot;&gt;bubble&lt;/a&gt; sort knowledge, but it just feels far too superficial. Additionally, I’m not necessarily saying that these individuals don’t know or can’t learn how to program, but all of these campaigns over years have been the same. You grab a few celebrities who quite obviously aren’t interested in this sort of thing and try to sell it to the audience. It’s quite painful for me to watch.&lt;/p&gt;

&lt;p&gt;A while back, Jeff Atwood wrote a nice &lt;a href=&quot;http://www.codinghorror.com/blog/2012/05/please-dont-learn-to-code.html&quot;&gt;article&lt;/a&gt;on a subject very similar regarding CodeAcademy’s New Year’s resolution “Code Year”. That article is directly applicable to this situation as well for the most part.&lt;/p&gt;

&lt;p&gt;Initially as a programmer, it’s easy to assume everybody should learn to code. After all, it’d make the world a better place right? Surely programming must be an essential skill set at this point that everybody should have?&lt;/p&gt;

&lt;p&gt;No. It’s a valuable skill set, but not a truly essential one.&lt;/p&gt;

&lt;h4 id=&quot;the-real-value-of-programming&quot;&gt;The real value of programming&lt;/h4&gt;
&lt;p&gt;Programming is many things, but at the end of the day it boils down to solving problems. It’s not about memorizing syntax and bashing out code, there’s a thought process behind it. Truly learning to program will give you insight on a whole new way to analyze and solve problems. In the process of learning to code, you will in turn gain a better understanding and respect for the various levels of technology upon which you are working with. It could help you more easily debug a problem you are having with say your computer or smart phone. Relatively mundane tasks can be simplified in day to day situations with just a little bit of programming knowledge.&lt;/p&gt;

&lt;p&gt;While I can understand the thought process behind teaching everybody how to program, I am not convinced that it is necessary. I think schools shouldn’t necessarily be focusing on teaching children to program, but rather teach them some general computer/internet concepts  (typing classes do not count). That would be far more valuable to the average person compared to teaching them what a while loop is.&lt;/p&gt;

&lt;p&gt;Growing up, I didn’t have any school courses that pertained to programming (or computers at all) although I was very interested in the subject. Had they been offered, I would’ve immediately signed up.&lt;/p&gt;

&lt;p&gt;If you have even the slightest interest in learning to code, do it. You will need to have patience and be persistent about it. It’s not something that happens overnight. If you really feel as though it’s not for you, that very well may be the case. However, if it is something that are genuinely interested in, here are a few tips:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Be patient. Trial and error can be the best instructor at times&lt;/li&gt;
  &lt;li&gt;Try to work on something you are truly passionate about&lt;/li&gt;
  &lt;li&gt;Don’t obsess over the language, framework, or platform&lt;/li&gt;
  &lt;li&gt;Google is your friend, but don’t become too dependent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Programming is not for everybody. Don’t force people, especially children, to learn to code. If you don’t have a passion to code, it will be a long and strenuous process. By forcing them to learn it, it could very well turn them off from it entirely. Let them be exposed to it on their own volition by providing the necessary tools and guidance should they be interested.&lt;/p&gt;
</description>
                                <pubDate>Tue, 10 Dec 2013 13:23:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/12/programming-as-an-essential-skill-set/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/12/programming-as-an-essential-skill-set/</guid>
                        </item>
                
                        <item>
                                <title>Spadille 1.6 - Better Late Than Never?</title>
                                <description>&lt;p&gt;Well, over a year and a half later, I suppose I should release Spadille 1.6 eh?&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/spadille-1.6.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/spadille-1.6.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spadille dropped off the grid a bit after being put on the back burner a while ago. I stopped working on it during the middle of refactoring…which is a bad idea. It’s been ready for release for a long time now, but I just never released it. Why do today what you can put off until tomorrow? This version does not support &lt;a href=&quot;https://sites.google.com/a/yvt.jp/openspades/&quot;&gt;OpenSpades&lt;/a&gt; yet, but I will release a quick patch shortly for it.&lt;/p&gt;

&lt;p&gt;You can download Spadille 1.6 &lt;a href=&quot;/projects/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Changelog:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Countless minor UI changes&lt;/li&gt;
  &lt;li&gt;Fixed a bunch of minor bugs&lt;/li&gt;
  &lt;li&gt;Improved memory usage&lt;/li&gt;
  &lt;li&gt;Improved threading&lt;/li&gt;
  &lt;li&gt;Rewrote screenshot hooking, caching and manager&lt;/li&gt;
  &lt;li&gt;Added dynamically populated server filters&lt;/li&gt;
  &lt;li&gt;Added share link&lt;/li&gt;
  &lt;li&gt;Added autocomplete to server browser&lt;/li&gt;
  &lt;li&gt;Added mumble link&lt;/li&gt;
  &lt;li&gt;Removed deprecated dependencies&lt;/li&gt;
  &lt;li&gt;Fixed support for Build and Shoot&lt;/li&gt;
  &lt;li&gt;Abstracted Spadille client and SpadilleDotNet library&lt;/li&gt;
  &lt;li&gt;Added “Last Played” column&lt;/li&gt;
  &lt;li&gt;Added intermediate dialog when joining server&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;related-notes&quot;&gt;Related Notes:&lt;/h4&gt;
&lt;p&gt;I’ll likely be releasing my library that Spadille is based on (along with a few other projects), SpadilleDotNet. It’s a C#/.NET (2.0 compliant) library that provides a lot of functionality for working with Ace of Spades Classic (Voxlap/OpenSpades), Build and Shoot, Ace of Spades 1.0, and more.&lt;/p&gt;

&lt;p&gt;Additionally, I have a few more tools that I’ll be releasing here soon as well, as I start to dig through old projects that I’ve not released, so keep an eye out.&lt;/p&gt;
</description>
                                <pubDate>Wed, 30 Oct 2013 14:31:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/10/spadille-1-6-better-late-than-never/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/10/spadille-1-6-better-late-than-never/</guid>
                        </item>
                
                        <item>
                                <title>C# - Global Hotkeys via GetAsyncKeyState</title>
                                <description>&lt;p&gt;Here’s a quick little class for implementing global hotkeys in C#/.NET 2.0+.&lt;/p&gt;

&lt;p&gt;As a bit of a preface, you could easily use &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309(v=vs.85).aspx&quot;&gt;RegisterHotKey&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windows/desktop/ms646327(v=vs.85).aspx&quot;&gt;UnregisterHotKey&lt;/a&gt; respectively to accomplish something like this, but this has a few caveats:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can’t register a key that has already been previously registered.&lt;/li&gt;
  &lt;li&gt;Some keys are reserved and cannot be registered, such as F12.&lt;/li&gt;
  &lt;li&gt;Although hacks exist, it’s not very ideal to easily implement with console applications due to the lack of a proper window handle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternatively, we can use another WinAPI function: &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx&quot;&gt;GetAsyncKeyState&lt;/a&gt;. It requires a bit more manual work, but it’s simple in the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: Without getting into semantics about what constitutes a proper “hook”, I’m just going to refer to the process of monitoring/polling key events via GetAsyncKeyState() as “hooking”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To keep things simple, the actually hooking process will use the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx&quot;&gt;Keys Enumeration&lt;/a&gt; and will marshall their underlying integral type during the P/Invoke. When a key is pressed, we will trigger the KeyPressed event.&lt;/p&gt;

&lt;h4 id=&quot;modifier-keys&quot;&gt;Modifier Keys&lt;/h4&gt;
&lt;p&gt;We don’t want to limit the hooking to just basic keys, instead will allow optional modifier keys using the ModifierKeys enum.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;hooking--unhooking&quot;&gt;Hooking &amp;amp; Unhooking&lt;/h4&gt;
&lt;p&gt;To hook a key, call the Hook() method, supplying the Keys value as well as any optional modifier keys. Additionally, you can provide a delegate to use for a callback for when the key is pressed.&lt;/p&gt;

&lt;p&gt;To unhook a key, simple call the Unhook() method with the appropriate parameters and it will no longer be polled.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyboard&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyboardHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;keyboard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrintScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;// do something&lt;/span&gt;
 
&lt;span class=&quot;n&quot;&gt;keyboard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Unhook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrintScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Internally, the hooked keys will be stored as KeyHook objects, which provide Keys and Modifiers properties.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyHook&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHookDelegate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Pressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHookDelegate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;prioritization&quot;&gt;Prioritization&lt;/h4&gt;

&lt;p&gt;For simple hotkeys, there won’t be any collisions. However, when you start mixing and matching modifier keys, things can get a little messy. To alleviate this issue, the hooked keys are sorted internally using a custom &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx&quot;&gt;IComparer&amp;lt;T&amp;gt;&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HookComparer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Implementation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Basically, it just compares hooked keys based on the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx&quot;&gt;Keys&lt;/a&gt; enumeration&lt;/li&gt;
  &lt;li&gt;Number of ModiferKeys set&lt;/li&gt;
  &lt;li&gt;Underlying ModifierKeys integral type summation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To sort the list, we use a simple lambda expression with our comparer:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HookComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;polling&quot;&gt;Polling&lt;/h4&gt;
&lt;p&gt;The underlying polling is based on a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx&quot;&gt;SystemTimer.Timer&lt;/a&gt;. According to &lt;a href=&quot;http://msdn.microsoft.com/en-us/windows/hardware/gg463266.aspx&quot;&gt;official Microsoft sources&lt;/a&gt;, this has a resolution of 15.6ms:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The default timer resolution on Windows 7 is 15.6 milliseconds (ms). Some applications reduce this to 1 ms, which reduces the battery run time on mobile systems by as much as 25 percent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m not about to perform a case steady on how fast a human can realistically type versus the timer interval, configure the interval as necessary. The polling itself can be enabled/disabled via the Enabled property. Additionally, polling is suppressed when hooking/unhooking keys.
During each tick, the key states are polled via PollKeyStates():&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PollKeyStates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;altPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controlPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ControlKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shiftPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShiftKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;32767&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;altPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controlPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shiftPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;KeyPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyPressedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When using GetAsyncKeyState() you need to pay attention to the most and least significant bits:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Normally when polling like these, we would end up triggering multiple KeyPressed events within a few milliseconds apart from each other. We can use the return value to get around this.&lt;/p&gt;

&lt;p&gt;A temporary List&lt;Keys&gt; is created which contains all hooked keys which are currently pressed. This way we don&apos;t need to call GetAsyncKeyState() while iterating over the hooked keys and we can prevent hook collisions. This is where the key sorting from earlier comes into play. We don&apos;t want to prematurely trigger a KeyPressed event for a different hooked key than expected.&lt;/Keys&gt;&lt;/p&gt;

&lt;p&gt;This isn’t necessarily a perfect solution but it works and is simple and flexible.&lt;/p&gt;

&lt;p&gt;Finally, here’s the complete class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*
* KeyboardHook.cs by Nate Shoffner
* http://nateshoffner.com
*/&lt;/span&gt;
 
&lt;span class=&quot;cp&quot;&gt;#region
&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Runtime.InteropServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Timers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Windows.Forms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Timer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Timers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;cp&quot;&gt;#endregion
&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;GlobalHotkeys&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyPressedEventArgs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventArgs&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyPressedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyboardHook&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Invokes&lt;/span&gt;
 
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DllImport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user32.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;short&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Delegates&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyHookDelegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventArgs&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Timer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyboardHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Timer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Interval&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Elapsed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_timer_Elapsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Enabled&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyPressedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHookDelegate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HookComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Unhook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RemoveAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_timer_Elapsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ElapsedEventArgs&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;PollKeyStates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PollKeyStates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;altPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controlPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ControlKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shiftPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShiftKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAsyncKeyState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;32767&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;altPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Control&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controlPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Shift&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shiftPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
                &lt;span class=&quot;n&quot;&gt;pressedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyPressed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;nf&quot;&gt;KeyPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyPressedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nested&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HookComparer&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HookComparer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Implementation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyCompare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetModifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifierCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CompareTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Implementation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nested&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyHook&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyHook&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;KeyHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModifierKeys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Modifiers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endregion&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</description>
                                <pubDate>Sun, 13 Oct 2013 20:44:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/10/c-global-hotkeys-via-getasynckeystate/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/10/c-global-hotkeys-via-getasynckeystate/</guid>
                        </item>
                
                        <item>
                                <title>Tabster 1.6 Released</title>
                                <description>&lt;p&gt;Random update time! I have a bad habit of not updating my applications for long periods of time…&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/tabster-1.6.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/tabster-1.6.png&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few weeks ago, I received a pingback from AddictiveTips where they wrote an &lt;a href=&quot;http://www.addictivetips.com/windows-tips/tabster-music-tablature-manager-with-search-store-view-options/&quot;&gt;article&lt;/a&gt;on Tabster. I’m still not sure why I just now received the PingBack when the article was published on March 29th of this year. This isn’t the first time Tabster has been reviewed by any means (and has also been used in schools), but it brought the neglected project to my attention.&lt;/p&gt;

&lt;p&gt;Well, much re-factoring later and Tabster 1.6 is ready.&lt;/p&gt;

&lt;p&gt;Change Log:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added “My Downloads” section&lt;/li&gt;
  &lt;li&gt;Added auto-scrolling&lt;/li&gt;
  &lt;li&gt;Added single-instance functionality&lt;/li&gt;
  &lt;li&gt;Added persistent window size/state&lt;/li&gt;
  &lt;li&gt;Added preview pane to library and search&lt;/li&gt;
  &lt;li&gt;Updated file formats&lt;/li&gt;
  &lt;li&gt;Caching is now forced&lt;/li&gt;
  &lt;li&gt;Removed auto-detect&lt;/li&gt;
  &lt;li&gt;Removed web browser&lt;/li&gt;
  &lt;li&gt;Fixed and improved searching&lt;/li&gt;
  &lt;li&gt;Added multi-downloader&lt;/li&gt;
  &lt;li&gt;Redesigned user interface&lt;/li&gt;
  &lt;li&gt;Refactored just about everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can download it on the &lt;a href=&quot;/projects/&quot;&gt;projects page&lt;/a&gt;.&lt;/p&gt;
</description>
                                <pubDate>Thu, 29 Aug 2013 11:02:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/08/tabster-1-6-released/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/08/tabster-1-6-released/</guid>
                        </item>
                
                        <item>
                                <title>Giving Credit Where Credit Is Due</title>
                                <description>&lt;p&gt;A few months back, I wrote a [post](http://www.nateshoffner.com/2013/03/a-well-deserved-apology “A Well-Deserved Apology) where I apologized to Mathew Kemp (aka Sniped) from Jagex. I finally felt as though I had some closure. Some peace of mind. Everything changed when the Jagex nation attacked.&lt;/p&gt;

&lt;p&gt;The other week, an interesting detail was brought to my attention. In a recent update of Ace of Spades, they decided to finally include some credits. Somebody showed me a screenshot of what appeared to be a smear campaign against the original developer. I figured it was Photoshopped, as no reputable company would target an individual like that.&lt;/p&gt;

&lt;p&gt;I decided to check in-game for myself and what do you know, there it was.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;Even in the darkest days when one of our best men, the lead programmer, proved to be a double agent and attempted to leave the building with sensitive intel! Fear not the cops always get their man.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a quick synopsis (as well as a bit of a preface) for those who don’t know, Ben Aksoy was the original developer of Ace of Spades. After selling the rights to Jagex, he later ended up working at their Cambridge office. In mid-late 2012, he was unhappy with the way things were being handled at the company and the direction in which the game was going, resulting in him putting in his final notice. After coming back from lunch one day, his hard drive in his personal laptop somehow magically broke, resulting in a BSOD. Additionally, stuff in his workspace was moved around. A fellow employee said the system admin had been at his desk. Upon approaching the sysadmin and asking about it, they denied everything.&lt;/p&gt;

&lt;p&gt;This sounds a bit like a conspiracy at first and maybe it is. But the point remains that the hard drive just spontaneously broke over a short time period. Additionally, I don’t think anybody is surprised by some methods companies use in order to “protect” intellectual property and how poorly they treat their employees. For reference, feel free to read some of the reviews from current/previous Jagex employees online.&lt;/p&gt;

&lt;p&gt;Before I propose my theory I have a bit of disclaimer. I’ll admit I have a bit of a personal bias against Jagex. On that same list is the Westboro Baptist Church, copyright/patent trolls, and whoever decided to cancel &lt;a href=&quot;http://en.wikipedia.org/wiki/Oreo_O&apos;s&quot;&gt;Oreo O’s&lt;/a&gt;. Basically, if you’re going to negatively impact/inhibit other people, society, or my morning ritual of pure bliss with milk, I’m going to have a personal bias against you.&lt;/p&gt;

&lt;h4 id=&quot;conspiracy-1&quot;&gt;Conspiracy #1&lt;/h4&gt;
&lt;p&gt;So this is my theory in tying the two incidents together. As soon as I read “attempted to leave the building with sensitive intel”, I immediately thought of that situation from a few months back. Perhaps Jagex was worried that Ben would be leaving with source code on his personal laptop. It seems like it’d be just tad extreme to destroy/swap a hard drive in order to protect an investment, but I wouldn’t rule it out entirely.&lt;/p&gt;

&lt;p&gt;As for the “Fear not the cops always get their man” part, I’m not really sure what that entails. I haven’t heard anything regarding Ben and the authorities. I may be looking too far into it, but regardless that’s quite a bit of slander.&lt;/p&gt;

&lt;h4 id=&quot;conspiracy-2&quot;&gt;Conspiracy #2&lt;/h4&gt;
&lt;p&gt;Let’s move on and analyze those credits. First we need to take a solid look at that middle paragraph:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;Even in the darkest days when one of our best men, the lead programmer, proved to be a double agent and attempted to leave the building with sensitive intel! Fear not the cops always get their man. But as a team everyone gathered together and rallied and before you stands a game we are all tremendously proud of, enjoyed by a community we have incredible respect for. gathered together and rallied behind the game. Before you stands a game we are all tremendously proud of, enjoyed by a community we have incredible respect for.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Anybody with a 2nd grade education is probably scratching their heads right now. Look at the last 2 sentences and how they repeat. No that wasn’t my typo, that’s in the game. It looks as though somebody made a last minute edit and copy/pasted the text without any final proof-read. Perhaps the text was just shifted to the right during the edit. If that’s the case, I would like to know whether this is something that was known before release or if it was edited in at the very last minute without anybody noticing.&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;Regardless of conspiracies, motives and other drama, one point still remains. I don’t care what company you work for. No company should be personally attacking an individual like this. Even moreso after everything he was put through until he finally had enough. Is it not bad enough that you ripped the guy off and made false promises, only to screw him over in the end? Then you recreate a watered-down copy of the game that panders to drooling Call of Duty kids while completely alienating the existing userbase. The game has severely flopped and you have yet to make a real profit off of it. Yet your priorities still seem to be personally attacking the developer. Good game. (No, not Ace of Spades 1.0. Are you even paying attention?)&lt;/p&gt;

&lt;p&gt;They made sure to give credit to Blitz Game Studios and Mat, but not the primary developer, at least not by name. It’s not as if they could’ve totally forgotten Ben’s involvement, which makes me think this was a known edit.&lt;/p&gt;

&lt;p&gt;We could give Jagex the benefit of the doubt. Maybe they aren’t referring to Ben. Maybe it’s just complete satire which just happens to fit that exact situation perfectly. Maybe Jagex didn’t break his hard drive in his laptop before leaving. Maybe Jagex’s “little brother” snuck in and edited the credits without anybody knowing. Who knows?&lt;/p&gt;

&lt;p&gt;Because I’m on a roll, here are some other points of interests within the credits:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;It has been a long and arduous campaign to get from a simple blocky green field to an international conflict involving hundreds of thousands of gamers.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ahem, “hundreds of thousands” should be changed to “hundreds”. Don’t flatter yourself. &lt;a href=&quot;http://www.vg247.com/2012/12/11/ace-of-spades-launches-tomorrow-500000-users-have-pre-registered/&quot;&gt;You may have made claims&lt;/a&gt; of several hundred thousand users before, but the actual stats say otherwise.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;Without the awesome Ace of Spades community we would have not been anywhere near the success we have been.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Actually, if you would’ve listened to the community for once, maybe the game would’ve had a chance at actually being a success. Try checking your forums, steam community, in-game players, and the rest of the internet.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;To those of you who directly contributed to building Ace of Spades from the very early days; the code contributors, the community team, the mappers, the modders and the third party software creators, we recognise your efforts and want to give you your very own 21 gun salute!&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As somebody who contributed with the development of the game, the community, as well as my own software, you can keep your salute. You already desecrated one developer, leave myself and any others out of it.&lt;/p&gt;

&lt;p&gt;And of course for reference, here are some screenshots of the credits:&lt;/p&gt;

&lt;div class=&quot;project-images-container&quot;&gt;	

        &lt;a href=&quot;/assets/images/posts/aoscredit1.jpg&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/aoscredit1.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/aoscredit2.jpg&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/aoscredit2.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

        &lt;a href=&quot;/assets/images/posts/aoscredit3.jpg&quot; class=&quot;fancybox&quot;&gt;
            &lt;img src=&quot;/assets/images/posts/aoscredit3.jpg&quot; class=&quot;img-fluid post-image&quot; /&gt;
        &lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;This post in no way reflects the collective opinion of Build and Shoot and/or Buld Then Snip, LLC.&lt;/p&gt;

&lt;h4 id=&quot;update-06172013&quot;&gt;Update (06/17/2013)&lt;/h4&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;As of July 13th (5 days after originally posting this entry), Jagex released an update for the game. The complete change log can be found [here](http://www.aceofspades.com/forums/showthread.php?20030-Update-Notes-13th-June-Discussion-Thread).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not included in that change log is the fact that they completely removed the credits page. Instead, there is an image in the background crediting Blitz Game Studios.&lt;/p&gt;

&lt;p&gt;So, kudos to Jagex for removing the defamatory messages from the credits, but they still failed to take responsibility for their mishap.&lt;/p&gt;

&lt;p&gt;Not surprised that once again, you guys have have half-assed the job.&lt;/p&gt;
</description>
                                <pubDate>Sun, 09 Jun 2013 01:51:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/06/giving-credit-where-credit-is-due/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/06/giving-credit-where-credit-is-due/</guid>
                        </item>
                
                        <item>
                                <title>A Well-Deserved Apology</title>
                                <description>&lt;p&gt;Months ago, amidst the chaos and commotion that is IRC, there were constant discussions with Jagex’s community managers Sniped (Mathew Kemp) and SallyTheButcher (Sally Da Costa). Conversation was often heated regarding the Ace of Spades community. This was primarily due to the Jagex community managers waving unwarranted sense of know-all in regards to the game and community based off “experience” from other games/communities. Most of which were dropped months after being launched, so they refused to properly cite said “experience”. Through all the bickering, I think it’s fair to say that nobody bumped heads more than Sniped and myself (IRC handle “StackOverflow”). This post is primarily directed at Sniped but occasionally Jagex as a whole.&lt;/p&gt;

&lt;p&gt;September 2nd, 2012:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[16:12] &amp;lt;@StackOverflow&amp;gt; this is a waste of time, you can&apos;t talk to people who are too self-absorbed in their own ways of doing things 
[16:12] &amp;lt;sniped&amp;gt; well, you can go and do something else Stack
[16:13] &amp;lt;@StackOverflow&amp;gt; sniped, you&apos;re too clueless to have the slightest idea of what we&apos;re doing
[16:13] &amp;lt;sniped&amp;gt; kk stack, well come back in 6 months and I&apos;ll accept your apology
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This quote is taken from a daily argument within an operator IRC channel (that we owned, mind you) and my statement was directed towards Build and Shoot, which at the time was being worked on privately.&lt;/p&gt;

&lt;p&gt;Well, here we are. 6 months later. We’ve both changed a lot since then, haven’t we? I sure have. I’ve grown to the point where I can freely admit my wrongdoings and feel no particular shame, but rather learn from them.&lt;/p&gt;

&lt;p&gt;So, lets get this going. I have a long, well deserved apology from myself to you:&lt;/p&gt;

&lt;h4 id=&quot;im-sorry-that-yourincompetenceandpersistentself-assurance-has-resulted-in-you-completely-alienating-yourselves-from-the-community-and-in-turn-the-game-entirely&quot;&gt;I’m sorry that your incompetence and persistent self-assurance has resulted in you completely alienating yourselves from the community and in turn, the game entirely&lt;/h4&gt;

&lt;p&gt;You had a great opportunity to turn this game into something great. Now I don’t mean this in the typical bitter 12 year old fashion. I mean you quite literally had a flourishing community and found a way to piss them off in nearly everywhere possible, some things I would’ve never seen coming. For that, I applaud you.&lt;/p&gt;

&lt;p&gt;I know instantly you would assume this is typical, biased banter. You seem to live in some weird alternate reality where Jagex does no wrong and you know the community well. With a game like Ace of Spades, community is everything. If you can’t handle the community, you are bound to fail. A vast majority of the heated flaming towards Jagex was (and still is) at least mildy constructive and yet you decide to focus on the unconstructive criticisms from 12 year olds. I’m not sure if you do this intentionally or you are just unable to differentiate between blatant flaming/trolling and constructive criticism. I’m assuming the latter since this was an ongoing problem on IRC, where you and Sally would focus on people spamming instead of people with legitimate questions (myself included).&lt;/p&gt;

&lt;p&gt;Danhezee and myself were often subject to blame for the community’s negative sentiment towards Jagex. Early on, that might have seemed like the case, sure, assuming people aren’t able to form an opinion on their own. It’s very easy to blame a handful of people instead of taking responsibility for your own mismanagement. However, it’s gotten to the point where the criticism has moved beyond just the community. For example, Gamasutra has written an article titled “&lt;a href=&quot;http://www.gamasutra.com/view/news/184246/How_Ace_of_Spades_gave_Jagex_a_lesson_in_community_management.php&quot;&gt;How Ace of Spades gave Jagex a lesson in community management&lt;/a&gt;”. All over the internet you see people complaining about the way Jagex failed to handle the community. I’m curious as to whether you are still so disillusioned as to think that this is the handy work of a few disgruntled individuals or if you’ve finally realized that you’re to blame.&lt;/p&gt;

&lt;h4 id=&quot;im-sorry-that-your-marketing-campaigns-have-backfired&quot;&gt;I’m sorry that your marketing campaigns have backfired&lt;/h4&gt;

&lt;p&gt;Early on, it was quite obvious you were a fan of numbers, saying things like “well, when we have 3 million players…” when discussing scalability, obsessing over Facebook “likes”, along with telling the community there were “over 500k” pre-registered players for 1.0. Scalability is great, but so is realism. At the time, the beta was holding a steady 3,800 players. This was without any sort of advertising and without updates for months on end.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Before release, there was a massive marketing campaign involving paying YouTubers (even though you try to deny it, it&apos;s obvious),  media outlets, and even &quot;major&quot; news outlets like [NBC](http://www.nbcnews.com/technology/ingame/machine-guns-meet-minecraft-ace-spades-1C6814146). (Because we all know NBC had nothing better to report than the release of Ace of Spades 1.0).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Promotional graphics were obviously rendered, which wouldn’t have been so much of an issue had you not openly stated they were in-game screenshots. Spoiler: They weren’t.&lt;/p&gt;

&lt;p&gt;Now, in retrospect, 1.0 can barely muster more than 1,500 players at any given time with the exception of when it is 50% off on Steam. Any game will sell well on Steam if it’s 50% off. Look a graph charting the playercounts over the last few months and you can easily determine when the game was on sale. 2-3 days after a steam sale, players drop right down to where they were beforehand.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/aos_10_stats_small.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/aos_10_stats_small.png&quot; align=&quot;left&quot; alt=&quot;Ace of Spades 1.0 Stats&quot; title=&quot;Ace of Spades 1.0 Stats&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is nothing that is captivating them. Sure, you got their money, but that’s not sustainable in the long term. Let’s do some math here. I’ve heard Valve takes roughly a 30% cut of sales, I’m not sure how accurate that is myself, if anybody knows for certain feel free to let me know, but it feels like a safe estimate. Based off that estimate, for every 1,000 copies you sell while it is 50% off, Jagex is only making $3,500. Keep in mind, they have been dumping money into this game since early-mid 2011. There have been massive advertising efforts, developer teams (both internal and external), third-party code payoffs (pyspades), servers, and more spanned over multiple years. This is in no way sustainable.&lt;/p&gt;

&lt;p&gt;Now there is paid DLC for sale, which is a whole discussion in itself. Even after saying there would be no paid DLC, I think they might be starting to realize that they aren’t going to break even. Next, they’ll likely start leasing privatized servers in an effort to cover server costs. Even though the game servers are hosted on cheap VPSs, it still adds up. People want the flexibility of open server software, not just locked down servers. Sadly, Jagex will still just look at this as another method for potential profit and half-ass it like always.&lt;/p&gt;

&lt;p&gt;Some of the primary factors in Ace of Spades’ marketing seem to be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Misleading figures&lt;/li&gt;
  &lt;li&gt;Misleading promotional content (graphics, maps, etc)&lt;/li&gt;
  &lt;li&gt;Misleading system specs. (The steam page claimed it required DirectX 9.0 for the longest time when the game uses OpenGL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have fun explaining those figures to your venture capitalists. (As a side note: Anybody who says you should buy 1.0 to “support” the developers, clearly has no idea how Jagex is financially structured.)&lt;/p&gt;

&lt;h4 id=&quot;im-sorry-that-your-lack-of-technical-prowess-has-come-back-to-bite-you-in-the-ass&quot;&gt;I’m sorry that your lack of technical prowess has come back to bite you in the ass&lt;/h4&gt;

&lt;p&gt;This was evidently a touchy subject, seeing as I was banned on the forums shortly after posting it on the forums.&lt;/p&gt;

&lt;p&gt;After seeing you write this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Sniped wrote: The botting issue in the prototype of AoS will not exist when it is fully released. Simple as that.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I replied with the statement below, resulting in me being banned for “flaming other users”.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lol. Please learn how aimbots work before making a statement like this.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This reminds me of a quote off of IRC:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;Sniped&amp;gt; if there is no cheating possible, would you need extra admin tools?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You shouldn’t make such bold implications, especially if they have no technical backing.&lt;/p&gt;

&lt;p&gt;People will cheat in 1.0 just as with any game. OpenGL as a technology is tried and tested when it comes to cheating.&lt;/p&gt;

&lt;p&gt;I wouldn’t consider idle legal threats as being a “wealth of experience”. I’ve done my fair share of anti-cheat measures, both technically and socially. I have real-world knowledge and real-world expectations about the subject. Blindly expecting Jagex to obliterate all cheating is quite preposterous. Especially when trying to pull a line like “We have a wealth of experience in dealing with bots too.”, when everybody knows Jagex has little to no control over the cheating in their headlining game.&lt;/p&gt;

&lt;p&gt;Protip: The average 12 year old who downloads an aimbot isn’t going to care about some idle legal threat. It’s quite laughable.&lt;/p&gt;

&lt;p&gt;I speak for myself when saying I don’t take a company seriously if they try to threaten a lawsuit against anybody who cheats in a game. If anything, it’s likely to stir up interest in people to make cheats as a sort of challenge.&lt;/p&gt;

&lt;p&gt;Also, mfw everybody is pretty much reiterating what I wrote in a post, only to have it deleted for being “libelous”. The only problem is my statement was based of of personal expereience from RuneScape, as well as public documentation regarding legalites between Jagex and cheaters. Basically, it’s proven and factual (although my personal experence with RS would be considered opinionated). That’s not anywhere near being “libelous”.&lt;/p&gt;

&lt;p&gt;This is just one of many examples where your lack of real-world experience/knowledge has come back to haunt you. By making bold statements and implications such as those, you ignited the interest in many individuals to create cheats, some of which were out on launch day. Why? I’ll give you a hint, people will always cheat. People will do it for whatever reason they want. But for those who make cheats, it’s generally for the challenge to do so and when you antagonize people with statements such as those, you’re only adding fuel to the fire. So congratulations. You not only proved how ignorant you are, but you also helped ruin the in-game experience for players.&lt;/p&gt;

&lt;p&gt;Here’s a little bit of advice. I know at Jagex, you guys are quote fond of extravagant (and rather pretentious) titles, but those titles are meaningless unless you have real knowledge, and more importantly, real-world experience. A popular trend among Jagex employees seems to be that of praising the “specialists” within the company. Any problem you can think of, there’s evidently a specialist for it. I’m not doubting that there are people who could know what they’re doing there, but if YOU don’t have an accurate estimation of their skillset, I’m not going to take your word for it. Not to mention, there are many track records with how Jagex has handled, or failed to handle certain situations. Take cheating for instance. You claim you have “anti-cheat specialists”. Where are they? I’m going to assume they’re not involved with Ace of Spades, otherwise you wouldn’t leave such gaping holes like leaving a god damn console within the game.&lt;/p&gt;

&lt;h4 id=&quot;im-sorry-for-your-skewedoutlook-of-build-and-shoot-and-its-denial-of-partnership&quot;&gt;I’m sorry for your skewed outlook of Build and Shoot and its denial of partnership&lt;/h4&gt;

&lt;p&gt;The Ace of Spades community as a whole was happy to see Build and Shoot carrying on support for the free to play version and the response to this by Jagex was censorship and bans. I could partially understand this from a company perspective. If people know there’s a free version, they’ll be less inclined to buy the paid version. However, it’s become quite apparent to everybody that the main reason for the irrational responses were the result of petty differences still lingering between the old Ace of Spades staff and Jagex’s community managers.&lt;/p&gt;

&lt;p&gt;As a result, the only people who were negatively effected by this was the community, not Build and Shoot. On the contrary, the constant censorship resulted in a Streisand effect and it became even more popular, so thank you for that.&lt;/p&gt;

&lt;p&gt;Build and Shoot extended its arms with Jagex in an attempt to patch things up. We tried appeasing Jagex by adding sections on our forums for the 1.0 release. After an exchange of emails, primarily with Sniped, we realized there was always a blockade between us and their appeasement. A snippet from the last email reads:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;The passion of your community has overflowed onto some of our other platforms, such as social media and Steam. We have mentioned this to you before but have yet to see any attempts by the site administrators to deal with this issue. This issue is not something which just affects us as the behavior of some of these people who represent your community is going to reflect badly on you.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As I mentioned earlier, you fail to take responsibility for your own mistakes and are under the severe delusion that we are responsible for the negative sentiment towards Jagex.&lt;/p&gt;

&lt;p&gt;Partnering with Build and Shoot would’ve only resulted positively for Jagex, yet petty, childish, disagreements still seem to be a problem. The community knows about Build and Shoot, so there’s no real point in censoring it. Partnership would’ve meant less work on your end in terms of moderation and would’ve helped appease the community greatly. It could’ve helped serve as a marketing advantage for new players who are introduced to Build and Shoot and could possibly become interested in 1.0, sadly you seemed to look at things through a very narrow scope.&lt;/p&gt;

&lt;p&gt;I’ll cut it short with the apologies. I’m sure there is more to say, but I feel all 3 people who have read this far want to stab me with a soldering iron for wasting their time. Thankfully I actually remembered to type this up today, as I wouldn’t want my punctual reputation to be blemished. As I said, the game has always been centered around the community. Your failure  to properly manage it has resulted in the entire game spiraling downward. Sorry you had to learn that the hard way.&lt;/p&gt;

&lt;p&gt;Amidst all of these apologies, I must grant you very sincere “thank you” for helping show me where having an undeserved sense of accomplishment and self-righteous attitude can get you. Second, I would like to thank you for helping make Build and Shoot what it is now and for it’s continuous growth. We have a thriving community that is completely decentralized. Any attempts at patching things up with Jagex has been mainly a philanthropic effort for the community. Granted we would get publicity, which is nice. But you have given us more than enough through your failed attempts at censoring us and the community.&lt;/p&gt;

&lt;p&gt;A while back, I was offered to work at Jagex  in Cambridge to help develop Ace of Spades. At the time it seemed like a fantastic opportunity. Sadly, I declined the offer, so we didn’t get to share this roller coaster experience as drinking buddies. But judging by your actions, incoherent thinking, and constantly tripping over yourself, you’ve been drunk this entire time.&lt;/p&gt;

&lt;p&gt;tl;dr Sorry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sincerely,&lt;/em&gt;
&lt;em&gt;Nate Shoffner,&lt;/em&gt;
&lt;em&gt;Senior apology specialist.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This post in no way reflects the collective opinion of Build and Shoot and/or Buld Then Snip, LLC.&lt;/p&gt;

&lt;h4 id=&quot;update-352013&quot;&gt;Update (3/5/2013):&lt;/h4&gt;

&lt;p&gt;It seems this article has been passed around quite a bit throughout Jagex.&lt;/p&gt;

&lt;p&gt;It has come to my attention that Jagex has been censoring this article on their platforms. Now this doesn’t come as a surprise due to the nature of the article, but their reason for doing so is a bit absurd, in my opinion. Initially, the reasoning for deleting the posts was because it mentioned Build and Shoot. Sorry that Build and Shoot’s success is starting to overshadow your own.&lt;/p&gt;

&lt;p&gt;One of the forum staff, lods, said this:&lt;/p&gt;

&lt;p&gt;“it’s directing people to a non constructive article which is full of inaccuracies…”&lt;/p&gt;

&lt;p&gt;This might be a biased opinion, but I’d say that the article was at least mildy constructive. As for “inaccuracies”, unless you can provide direct examples, don’t say anything. Maybe instead of just skimming the article and making a baseless assumption, you could actually read it before claiming there are “inaccuracies”.&lt;/p&gt;

&lt;p&gt;Jagex’s response to this article has done nothing but prove the very behavior it was criticizing.&lt;/p&gt;

&lt;p&gt;Thanks for proving my point, again.&lt;/p&gt;
</description>
                                <pubDate>Sat, 02 Mar 2013 17:53:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/03/a-well-deserved-apology/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/03/a-well-deserved-apology/</guid>
                        </item>
                
                        <item>
                                <title>C# - Reusable Portable Application Settings</title>
                                <description>&lt;p&gt;Anybody who has worked with the .NET Framework has likely dealt with the native configuration files, especially if you’re using something as intuitive as Visual Studio. While the native functionality is pretty nifty, there’s still one small gripe myself and many other developers have. The .NET Framework is designed in a way that applications are to interface with a single configuration file whose location is found somewhere between AppData and obscurity. The reason for this design, according to Microsoft, was to alleviate the possibility of overwrite collisions between different applications. Despite being asked to allow developers to manage their own relative configuration paths, Microsoft has stood by this design. It’s quite an annoying “feature”, but there are workarounds, albeit tedious. This &lt;a href=&quot;http://www.geek-republic.com/2010/11/c-portable-settings-provider&quot;&gt;article&lt;/a&gt; provides a good bit of insight on how to tackle something like this. by inheriting the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.configuration.settingsprovider.aspx&quot;&gt;SettingsProvider&lt;/a&gt; class.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Specialized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Linq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Win32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Xml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Xml.Serialization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PortableSettingsProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Define some static strings later used in our XML creation&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// XML Root node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLROOT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configuration&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Configuration declaration node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONFIGNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configSections&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Configuration section group declaration node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GROUPNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sectionGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// User section node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;userSettings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Application Specific Node&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.Properties.Settings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Xml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
 
 
    &lt;span class=&quot;c1&quot;&gt;// Override the Initialize method&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NameValueCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Override the ApplicationName property, returning the solution name.  No need to set anything, we just need to&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// retrieve information, though the set method still needs to be defined.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Simply returns the name of the settings file, which is the solution name plus &quot;.config&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.config&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Gets current executable path in order to determine where to read and write the config file&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FileInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DirectoryName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Retrieve settings from the configuration file&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetPropertyValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Create a collection of values to return&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Create a temporary SettingsPropertyValue to reuse&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SettingsPropertyValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Loop through the list of settings that the application has requested and add them&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// to our collection of return values.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SettingsPropertyValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsDirty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     
    &lt;span class=&quot;c1&quot;&gt;// Save any of the applications settings that have changed (flagged as &quot;dirty&quot;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetPropertyValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Set the values in XML&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsPropertyValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spVal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;SetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Write the XML file to disk&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Combine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Create an informational message for the user if we cannot save the settings.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Enable whichever applies to your application type.&lt;/span&gt;
             
            &lt;span class=&quot;c1&quot;&gt;// Uncomment the following line to enable a MessageBox for forms-based apps&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//System.Windows.Forms.MessageBox.Show(ex.Message, &quot;Error writting configuration file to disk&quot;, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Uncomment the following line to enable a console message for console-based apps&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//Console.WriteLine(&quot;Error writing configuration file to disk: &quot; + ex.Message);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Check if we already have accessed the XML config file. If the xmlDoc object is empty, we have not.&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
                &lt;span class=&quot;c1&quot;&gt;// If we have not loaded the config, try reading the file from disk.&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Combine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
                &lt;span class=&quot;c1&quot;&gt;// If the file does not exist on disk, catch the exception then create the XML template for the file.&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// XML Declaration&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlDeclaration&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateXmlDeclaration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create root node and append to the document&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XMLROOT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rootNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create Configuration Sections node and add as the first node under the root&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;configSections&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CONFIGNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PrependChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the user settings section group declaration and append to the config node above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;sectionGroup name=&quot;userSettings&quot;...&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GROUPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Configuration.UserSettingsGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the Application section declaration and append to the groupNode above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;section name=&quot;AppName.Properties.Settings&quot;...&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;section&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Configuration.ClientSettingsSection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the userSettings node and append to the root node&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;userSettings&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the Application settings node and append to the userNode above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;AppName.Properties.Settings&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Retrieve values from the configuration file, or if the setting does not exist in the file,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// retrieve the value from the application&apos;s default configuration&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Search for the specific settings node we are looking for in the configuration file.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If it exists, return the InnerText or InnerXML of its first child node, depending on the setting type.&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// If the setting is serialized as a string, return the text stored in the config&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// If the setting is stored as XML, deserialize it and return the proper object.  This only supports&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// StringCollections at the moment - I will likely add other types as I use them in applications.&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;XmlSerializer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]));&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlTextReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlNodeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Collections.Specialized.StringCollection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;StringCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Check to see if a default value is defined by the application.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If so, return that value, using the same rules for settings stored as Strings and XML as above&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;XmlSerializer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]));&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlTextReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlNodeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
                    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Collections.Specialized.StringCollection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;StringCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                        &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsPropertyValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Define the XML path under which we want to write our settings if they do not already exist&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;XmlNode&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Search for the specific settings node we want to update.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If it exists, return its first child node, (the &amp;lt;value&amp;gt;data here&amp;lt;/value&amp;gt; node)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// If we have a pointer to an actual XML node, update the value stored there&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Write the object to the config serialized as Xml - we must remove the Xml declaration when writing&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// the value, otherwise .Net&apos;s configuration system complains about the additional declaration.&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&amp;lt;?xml version=&quot;&quot;1.0&quot;&quot; encoding=&quot;&quot;utf-16&quot;&quot;?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If the value did not already exist in this settings file, create a new entry for this setting&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Search for the application settings node (&amp;lt;Appname.Properties.Settings&amp;gt;) and store it.&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;XmlNode&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmpNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Create a new settings node and assign its name as well as how it will be serialized&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;setting&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
             
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;serializeAs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;serializeAs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Xml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Append this node to the application settings node (&amp;lt;Appname.Properties.Settings&amp;gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tmpNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Create an element under our named settings node, and assign it the value we are trying to save&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;XmlElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Write the object to the config serialized as Xml - we must remove the Xml declaration when writing&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// the value, otherwise .Net&apos;s configuration system complains about the additional declaration&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&amp;lt;?xml version=&quot;&quot;1.0&quot;&quot; encoding=&quot;&quot;utf-16&quot;&quot;?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;           
 
            &lt;span class=&quot;c1&quot;&gt;//Append this new element under the setting node we created above&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;deserialization-bug&quot;&gt;Deserialization Bug&lt;/h4&gt;
&lt;p&gt;Immediately I found a bug during deserialization using &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx&quot;&gt;ArrayList&lt;/a&gt; or &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.collections.specialized.stringcollection.aspx&quot;&gt;StringCollection&lt;/a&gt; within GetSetting(). It seems that the collection was being cast to a string array during deserialization. Luckily this is a simple fix:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;{0}&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;{0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     
    &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]));&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlTextReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlNodeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
                &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Collections.Specialized.StringCollection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                    &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;making-it-reusable&quot;&gt;Making it Reusable&lt;/h4&gt;
&lt;p&gt;Great, now it works perfectly. However, I’m far too lazy to copy this snippet into every project, I’d much prefer to reuse it from a referenced library. In order to do this, you’ll have to make use of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly.aspx&quot;&gt;GetEntryAssembly()&lt;/a&gt;. This will allow you to reference the portable settings class within any assembly.
Some words of caution: This solution is dependent on the calling assembly name. It will create a directory in the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx&quot;&gt;ApplicationData&lt;/a&gt; folder using the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.environment.getfolderpath.aspx&quot;&gt;Environment.GetFolderPath()&lt;/a&gt; method and then create the appropriate configuration file using the same name. Use it at your own risk and with common sense, especially if you plan on using this in any sort of production software.&lt;/p&gt;

&lt;p&gt;Create a standard library (DLL) and add the following class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PortableSettingsProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLROOT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configuration&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// XML Root node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONFIGNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configSections&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Configuration declaration node     &lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GROUPNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sectionGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Configuration section group declaration node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;userSettings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// User section node&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Application Specific Node&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Store instace of calling assembly&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entryAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entryAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Check if we already have accessed the XML config file. If the xmlDoc object is empty, we have not.&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
                &lt;span class=&quot;c1&quot;&gt;// If we have not loaded the config, try reading the file from disk.&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Combine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// If the file does not exist on disk, catch the exception then create the XML template for the file.&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// XML Declaration&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateXmlDeclaration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create root node and append to the document&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XMLROOT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rootNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create Configuration Sections node and add as the first node under the root&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;configSections&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CONFIGNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PrependChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the user settings section group declaration and append to the config node above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;sectionGroup name=&quot;userSettings&quot;...&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GROUPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Configuration.UserSettingsGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;configNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the Application section declaration and append to the groupNode above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;section name=&quot;AppName.Properties.Settings&quot;...&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;section&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Configuration.ClientSettingsSection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;groupNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the userSettings node and append to the root node&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;userSettings&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USERNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
                    &lt;span class=&quot;c1&quot;&gt;// Create the Application settings node and append to the userNode above&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;// &amp;lt;AppName.Properties.Settings&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;userNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Override the Initialize method&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NameValueCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;entryAssembly&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetEntryAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
        &lt;span class=&quot;n&quot;&gt;ConfigName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entryAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;n&quot;&gt;ConfigDirectory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Combine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFolderPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SpecialFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entryAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConfigDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConfigDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.Properties.Settings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
 
        &lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Simply returns the name of the settings file, which is the solution name plus &quot;.config&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{0}.config&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApplicationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Gets current executable path in order to determine where to read and write the config file&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//return new FileInfo(callingAssembly.Location).DirectoryName;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Override the ApplicationName property, returning the solution name.  No need to set anything, we just need to&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// retrieve information, though the set method still needs to be defined.&lt;/span&gt;
 
 
    &lt;span class=&quot;c1&quot;&gt;// Retrieve settings from the configuration file&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetPropertyValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Create a collection of values to return&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Create a temporary SettingsPropertyValue to reuse&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Loop through the list of settings that the application has requested and add them&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// to our collection of return values.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SettingsPropertyValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsDirty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)};&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Save any of the applications settings that have changed (flagged as &quot;dirty&quot;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetPropertyValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingsPropertyValueCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Set the values in XML&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsPropertyValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spVal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingsColl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;SetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// Write the XML file to disk&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Combine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAppPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSettingsFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Create an informational message for the user if we cannot save the settings.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Enable whichever applies to your application type.&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Uncomment the following line to enable a MessageBox for forms-based apps&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//MessageBox.Show(ex.Message, &quot;Error writting configuration file to disk&quot;, MessageBoxButtons.OK, MessageBoxIcon.Error);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Uncomment the following line to enable a console message for console-based apps&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//Console.WriteLine(&quot;Error writing configuration file to disk: &quot; + ex.Message);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;c1&quot;&gt;// Retrieve values from the configuration file, or if the setting does not exist in the file,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// retrieve the value from the application&apos;s default configuration&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Search for the specific settings node we are looking for in the configuration file.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If it exists, return the InnerText or InnerXML of its first child node, depending on the setting type.&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// If the setting is serialized as a string, return the text stored in the config&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// This solves the problem with StringCollections throwing a NullReferenceException&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;{0}&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;{0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Check to see if a default value is defined by the application.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If so, return that value, using the same rules for settings stored as Strings and XML as above&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]));&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;XmlTextReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlNodeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
                    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settingType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Collections.Specialized.StringCollection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
                        &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingsPropertyValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Define the XML path under which we want to write our settings if they do not already exist&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;XmlNode&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Search for the specific settings node we want to update.&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If it exists, return its first child node, (the &amp;lt;value&amp;gt;data here&amp;lt;/value&amp;gt; node)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//setting[@name=&apos;{0}&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FirstChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
        &lt;span class=&quot;c1&quot;&gt;// If we have a pointer to an actual XML node, update the value stored there&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Write the object to the config serialized as Xml - we must remove the Xml declaration when writing&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// the value, otherwise .Net&apos;s configuration system complains about the additional declaration.&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;SettingNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&amp;lt;?xml version=&quot;&quot;1.0&quot;&quot; encoding=&quot;&quot;utf-16&quot;&quot;?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// If the value did not already exist in this settings file, create a new entry for this setting&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Search for the application settings node (&amp;lt;Appname.Properties.Settings&amp;gt;) and store it.&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmpNode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//{0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectSingleNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//{0}.Properties.Settings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;APPNODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Create a new settings node and assign its name as well as how it will be serialized&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;setting&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;serializeAs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Xml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Append this node to the application settings node (&amp;lt;Appname.Properties.Settings&amp;gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tmpNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;// Create an element under our named settings node, and assign it the value we are trying to save&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmlDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Write the object to the config serialized as Xml - we must remove the Xml declaration when writing&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// the value, otherwise .Net&apos;s configuration system complains about the additional declaration&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnerXml&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&amp;lt;?xml version=&quot;&quot;1.0&quot;&quot; encoding=&quot;&quot;utf-16&quot;&quot;?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
            &lt;span class=&quot;c1&quot;&gt;//Append this new element under the setting node we created above&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;newSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;valueElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;assigning-the-providerbase&quot;&gt;Assigning the ProviderBase&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/posts/vs-portable-settings.png&quot; class=&quot;fancybox&quot;&gt;
    &lt;img src=&quot;/assets/images/posts/vs-portable-settings.png&quot; align=&quot;left&quot; alt=&quot;Visual Studio Properties&quot; title=&quot;Visual Studio Properties&quot; class=&quot;img-fluid post-image&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, open your Visual Studio solution and go to the Settings tab located in the project properties for the appropriate project. For each of the settings that you want to make portable, modify the “Provider” property to represent the namespace scheme for your portable settings class. You will have to modify the provider property for each subsequent setting if you want it to remain portable. It can be a bit of a hassle, but in the end, it’s a small cost for better control.&lt;/p&gt;

&lt;p&gt;I have been using this code for a few years now on a few smaller projects with no problems. As I’ve stated, it’s not perfect, but it’s still an alright solution, assuming you use it properly.&lt;/p&gt;
</description>
                                <pubDate>Thu, 24 Jan 2013 05:19:00 +0000</pubDate>
                                <link>https://nateshoffner.com//blog/2013/01/c-reusable-portable-application-settings/</link>
                                <guid isPermaLink="true">https://nateshoffner.com//blog/2013/01/c-reusable-portable-application-settings/</guid>
                        </item>
                
        </channel>
</rss>