One of my fetishes is including as much resources as possible within the executable. This is fairly easy to do with Visual Studio. Just select desired file and change Build Action property to Embedded Resource.
Biggest benefit is that you can count on file always being there. There is no need to add file to installer nor to do error handling. And, even when you need to have user-modifiable files, you can always tuck away safe defaults far out of reach of an inexperienced user.
When you have XML file stored as this, loading is as easy as it gets:
var doc =newXmlDocument();var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("project.example.xml");
doc.Load(stream);
However, when you have that same file linked to it’s DTD (Document Type Definition) things get ugly. Only thing that we get with our function is FileNotFoundException with Could not find file 'C:\somepath\example.dtd'. Things do not change even when DTD is embedded next to XML. As you can see from exception, our XmlDocument is stubbornly reading DTD from disk instead from resources.
Easiest solution is to delete referring DOCTYPE from XML document. However, that is double-edged sword since that also means that you lose quite a good helping hand in detecting early errors. I will not even go into how (properly created) DTD can be huge help with intellisense during XML editing.
Better solution would be to use XmlDocument’s existing XmlResolver property. XmlResolver is what actually handles from where each stream is read. If we inherit that class we can make critical change to read DTD from resource stream instead from file system. And it all fits in single overridden function:
Whenever I design board with PIC I need ICSP connector. And connectors take space.
Therefore I started used Au Group Electronics connector soldered to simple cable that plugged into PICkit. By using pogo pins I could put six through-hole pads on borad and have connectivity. Works nicely and it is as cheap as it goes.
That did worked but connector was weak spot. No matter how you hold it, there was need to re-solder broken wire every few weeks. Not too annoying, I guess…
Well, I found myself a new personal favorite.
Mill-max has a nice pogo connector “clearly” named 829-22-006-20-001101. Out of box it comes as 90° PCB-mountable connector but, with the help of pliers, I straightened those pins and they fit perfectly into PICkit 3 (they actually hold better than straight pins). Now I can press onto my board’s pads with whole PICkit and that feels much better.
There is only small issue of fitting into snug spaces. With cable you can get into any space, with this “connector” things work better if connector is at board’s edge. But it is small price to pay.
P.S. Connector is available from both DigiKey and Mouser.
P.P.S. Yes, connector works with both PICkit 2 and PICkit 3.
Easiest way to check whether file is valid after download is to grab it’s SHA-1 sum. Most commonly it has same name as file but with additional .sha1 extension (e.g. temp.zip would have SHA-1 sum in temp.zip.sha1). One annoyance is how to generate all those .sha1 files…
To make my life little bit easier, I made a bash script. This script will go through given directories and create all SHA-1 sums. I use content and download directories in this case:
Probably some explanation is in order. Script check each file in content and download directories. If file ends in .sha1 (bottom of the script), we will just remove that file and log action with minus (-) sign. This serves as clean-up for orphaned SHA-1 sums.
If file does exist, we need to check existing SHA-1 sum. If there is no sum script will just create one and log it with plus (+) sign. If sum does exist, script compares it with newly generated value. If both match, there is nothing to do, if they do not match, that is logged with X character.
Example output would be:
/public_html/download/qtext301.exe
+ /public_html/download/qtext310.exe
X /public_html/download/seobiseu110.exe
- /public_html/download/temp.zip
Here we can see that sum for qtext301.exe was valid and no action was taken. Sum for qtext310.exe was added and one for seobiseu110.exe was fixed (it’s value didn’t match). File temp.zip.sha1 was removed since temp.zip does not exist anymore.
P.S. While this code is not perfect and it might not be best solution, it does work for me. :)
As I was finishing my order of MSDN magazine I was puzzled with one field. It said “In lieu of a signature, we require a unique identifier. In what month were you born?”
I am not quite sure in what universe month of birth is even close to being unique…
P.S. For this example I used ff08::1 as multicast address. You might want to change this to something not as usual as this (but compliant to ffx8::/16). E.g. ff28::1:2:3:4:5 might do the trick.