Friday, December 29, 2006

The Easter Egg

Recently I had a little fun in an application I was developing. I really like the concept of Easter Eggs in software. The one below is interesting in that it pulls the unofficial Dilbert feed and displays it in a picture box. The form that this is on resizes the controls however there is a section of "dead space" where you couldn't reasonably resize a control. I decided to use this space to place a picture box. If you double click the picture box 5 times, it will go to the web and pull the image.

A few notes:
  • Don't do this if you're going to get your butt chewed.
  • Don't blame me if you do.
  • Make sure you encapsulate your code in try blocks and throw out exceptions. Then you don't have to worry about someone inadvertently finding your Easter Egg and pointing out the bug.
  • I used the #region preprocessor to hide the code. I used something like EE and then hid it in an obscure place in the code. It's unlikely another developer is going to find it at a later date unless they notice it. Generally if they do they'll leave it there anyhow after laughing at it.

If someone does use this code, I'd REALLY like to know. I had a few laughs putting this in place.





#Region "EE"
' Thanks Duncan! - http://www.duncanmackenzie.net/blog/Reading-An-Image-from-the-web/
Function GetImageFromURL(ByVal url As String) As Byte()
Dim wr As HttpWebRequest = _
DirectCast(WebRequest.Create(url), HttpWebRequest)
Dim wresponse As HttpWebResponse = _
DirectCast(wr.GetResponse, HttpWebResponse)
Dim responseStream As Stream = wresponse.GetResponseStream
Dim br As BinaryReader = New BinaryReader(responseStream)
Dim bytesize As Long = wresponse.ContentLength
Return br.ReadBytes(bytesize)
End Function
Private Sub pbEE_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles pbEE.DoubleClick
Try
If pbEE.Tag Is Nothing Then
pbEE.Tag = 0
End If
pbEE.Tag += 1
If pbEE.Tag < 5 Then
Exit Sub
End If
If pbEE.Image Is Nothing Then
Dim enc As System.Text.UTF7Encoding
Dim xmlDil As New Xml.XmlDocument
Dim xmlNode As Xml.XmlNode
Dim s As String = System.Text.Encoding.ASCII.GetString(GetImageFromURL("http://feeds.feedburner.com/tapestrydilbert.xml"))
xmlDil.LoadXml(s)
xmlNode = xmlDil.SelectSingleNode("/rss/channel/item/enclosure")
Debug.WriteLine(xmlNode.Attributes.GetNamedItem("url").InnerText)
pbEE.Image = New Bitmap(New IO.MemoryStream(GetImageFromURL(xmlNode.Attributes.GetNamedItem("url").InnerText)))
Else
pbEE.Image = Nothing
pbEE.Refresh()
Dim canvas As Graphics = pbEE.CreateGraphics
canvas.Clear(pbEE.BackColor)
canvas.DrawString("Congratulations, you found the easter egg!", _
New Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point), _
New SolidBrush(Color.DarkRed), 1, 1)
canvas.DrawString("Software Developers for this application:",_
New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular, _
GraphicsUnit.Point), New SolidBrush(Color.DarkBlue), 1, 40)
canvas.DrawString("Robert Mech, Others...", _
New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular, _
GraphicsUnit.Point), New SolidBrush(Color.DarkBlue), 1, 53)
canvas.DrawString("Double-Click to get dilbert back.", _
New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular, _
GraphicsUnit.Point), New SolidBrush(Color.Black), 1, 74)
canvas.DrawString("Move the mouse out of the window to clear this screen.", _
New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular, _
GraphicsUnit.Point), New SolidBrush(Color.Black), 1, 86)
canvas.Dispose()
End If
Catch ex As Exception
Debug.WriteLine(ex)
End Try
End Sub
Private Sub pbEE_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles pbEE.MouseLeave
Try
pbEE.Image = Nothing
Catch ex As Exception

End Try
End Sub
#End Region

Wednesday, November 29, 2006

Version Checking Class for PAD files.

Last Night I wrote what I thougt was some really brilliant code for checking a PAD file for the proper version. For my software I keep a pad file online which allows me to simply upload the PAD file for my software to another site. It also allows me to use the same file to check the version in my software. Here is the class that I use to do this. Calling it is really simple, just invoke the method with the current version and the URL to the pad file. If there is no internet access or an error, it returns that there is no update available.





Imports System.io
Imports System.Net
Imports System.Text
Imports System.Xml
Imports System.Xml.XmlDocument
Public Class clsCheckVersion
Private strListedVersion As String
Private strDownloadURL As String
Private strApplicationInfoURL As String
Public ReadOnly Property ListedVersion() As String
Get
Return strListedVersion
End Get
End Property
Public ReadOnly Property PrimaryDownloadURL() As String
Get
Return strDownloadURL
End Get
End Property
Public ReadOnly Property ApplicationInfoURL() As String
Get
Return strApplicationInfoURL
End Get
End Property
Public Function CheckVersion(ByVal strCurrentVersion As String, ByVal strPadFile As String) As Boolean
Try
Dim xmlPad As New Xml.XmlDocument
Dim xmlNode As XmlNode
Dim strXMLFileName As String
strXMLFileName = GetURL(strPadFile)
xmlPad.Load(strXMLFileName)

' Primary Download URL (not required)
Try
xmlNode = xmlPad.SelectSingleNode("/XML_DIZ_INFO/Web_Info/Download_URLs/Primary_Download_URL")
strDownloadURL = xmlNode.InnerText
Catch ex As Exception
strDownloadURL = ""
End Try

' Primary Application info URL (Not Required)
Try
xmlNode = xmlPad.SelectSingleNode("/XML_DIZ_INFO/Web_Info/Application_URLs/Application_Info_URL")
strApplicationInfoURL = xmlNode.InnerText
Catch ex As Exception
strApplicationInfoURL = ""
End Try

' Required Program version, if not present, exception fired and returns false (no new version information available)
xmlNode = xmlPad.SelectSingleNode("/XML_DIZ_INFO/Program_Info/Program_Version")
' Compare Version length based on dest this is in case build information is not
' included in the version in the pad file.
strListedVersion = xmlNode.InnerText.Trim()
If strCurrentVersion.StartsWith(xmlNode.InnerText.Trim()) Then
CheckVersion = False
Else
CheckVersion = True
End If
xmlPad = Nothing
System.IO.File.Delete(strXMLFileName)
Catch ex As Exception
Debug.WriteLine(ex.ToString)
CheckVersion = False
End Try
End Function
Public Function GetURL(ByVal destURL As String) As String
Dim oWebReq As HttpWebRequest = CType(WebRequest.Create(destURL), HttpWebRequest)
Dim oWebResp As HttpWebResponse = CType(oWebReq.GetResponse(), HttpWebResponse)
Dim oStream As Stream = oWebResp.GetResponseStream()
Dim objXMLStream As StreamWriter
GetURL = System.IO.Path.GetTempFileName
Debug.WriteLine(GetURL)
objXMLStream = System.IO.File.CreateText(GetURL)
Dim iByte As Integer
iByte = oStream.ReadByte
While iByte <> -1
objXMLStream.Write(Chr(iByte))
iByte = oStream.ReadByte
End While
objXMLStream.Close()
End Function
End Class

Wednesday, November 15, 2006

Quick Test Case


Quick Test Case (Or QTC) give programmers an QA staff with limited time and budget the ability to develop effective test cases for application testing.



Many software development departments and independent programmers lack the time and money to properly test software. The reality is that many companies fail to see the benefit in software engineering and testing regardless of the proven benefits.



QTC It is not designed to be a fully featured UML or other CASE tool but a low budget alternative. With QTC you can develop test cases while you are coding your software. In eXtreme Programming (XP) environments testing is often overlooked. QTC allows you to get test cases written quickly.




QTC also allows smaller programming shops a leg up in quality. Often software publishers do no more testing than what the programmer can think of. Using QTC allows you to write test cases and allow others to interact with the published documents.



QTC Features:

  • Uses most common elements of test case design.
  • Easy to tab-through interface allows the test case writer to write cases quickly.
  • Easy to spot icons show case status at a glance.
  • Case documents are in XML which can be imported into future CASE products.
  • Reports of any kind can be written with XSLT.
  • It's Free!





    Downloading And Installation


    Simply download the file, and run the .MSI installer.



    QTCSetup.msi

Wednesday, October 18, 2006

PhotoCopy


PhotoCopy is a plug in that allows you to copy files from your memory card, to the photo location in gppvr. You can also rotate and preview photos before copying.


Downloading and Installing

The latest version of the PhotoCopy plugin is v1.1. PhotoCopy.zip



Requirements

This plugin has been tested with GB-PVR v98.8b



Configuration

You must have at least 1 “Photo Folder” already setup in GBPVR under config. Because this is a new Plugin there are no skins available for it. Because of this, you’ll need to move the skin\blue\PhotoCopy directory in the zip file (which contains the skin.xml file) into your skin directory. If you are using the BLUE skin (GBPVR DEFAULT) then simply unzipping this into your GBPVR directory will work just fine.



Using the Plugin


You’ll need to select the source. Just use the SRC button to change to which drive you want to copy from. Then, select the destination. You’ll do this by using the DST: button. This is read from the config.xml in GBPVR. You choose these based on what’s setup in the config.



Then click SCAN MEDIA and it will go through and find all pictures on the disk.



From there you’ll need to go through each one and move it or copy it.



There is no “Copy All” button yet, this is by design. I felt that the whole reason I was writing this is because I needed to rotate pictures before moving them. If I copy all of them I’m back to where I stared.



CONTROLS: The controls are based off of the STANDARD keymappings. Here are what controls will respond



UP, DOWN, LEFT, RIGHT



>> = ^F (Rotate Picture)



<< = ^D (Rotate Picture the other way)



REC = ^K - Move File to destination folder



PLAY = ^P - Copy file to destination folder



ESC/EXIT = ESC



Support

This plugin is discussed in the Developers forum

Blinky

Blinky is a plug in for GBPVR (http://www.gbpvr.com/) where it will light up the scroll lock key (or flash it) when it’s recording a show. Useful if you have a remote keyboard receiver with the lights on it (like I have). Then you can see a recording is in progress without looking at GBPVR or the TV screen.


Downloading and Installing

The latest version of the Blinky plugin is v1.0.2 Blinky.zip the blink.xml to the gbpvr root directory.


Once you have done this, load up the config app for GBPVR, and UNCHECK it in the plugin menu. It is not necessary for use, it doesnt have an interface anyhow.
That’s it, your scroll lock light will light up when recording.



Requirements

A scroll lock light where it’s visible. :)

This plugin has been tested with GB-PVR v98.08 and above

Configuration


You can customize the blinky.xml file to get some advanced features like a file that will show you what’s recording at the current time. Useful for other programs? Who knows.




blinky.xml tag Values


REFRESH is the time in miliseconds to refresh. This also controls flash so if you have this ”on” for 30000 milliseconds (30 seconds), it’s also off for 30000 seconds. Also,
for low horsepower systems every flash results in disk io and processing.
FLASH controls if you want flashing or just a steady scroll lock key light.


WRITEFILE controls if you want an output file (see what it contains below)


WRITEFILENAME controls the output path/filename for the file.

Output file will contain information on EACH show currently recording. So if you have more than 1 tuner recording you SHOULD have more than one entry in here. Since I only have 1 tuner, I can test this yet.


blinky.rec file example

------------------------------------
# Blinky Record Status File
Currently Recording: Days of our Lives
Start Time : 10/9/2006 1:00:00 PM
End Time : 10/9/2006 2:00:00 PM
File Name : C:\Days of our Lives\Days of our Lives_20061009_13001400.mpg
-----------------------------------------

Support

This plugin is discussed in the Developers forum

Friday, October 06, 2006

HARDWARE: Creating My own PVR for HDTV (ATSC) on a budget.

My installation from the get-go was a modest one. I didn't have a million bucks to throw into a PVR, just some spare parts and the purchase of the $39.99 Technisat Air2Pc card (eBay) and the Purvideo decoder $19.99. The rest I had already at the house.

Hardware Used:
Athlon XP 1600+ CPU
NVidia GeForce 5200 25MB Card (XFX Brand)
250GB Maxtor ATA-133 Drive
PC2700 Memory
Technisat Air2Pc (Generation 1) ATSC Card (BDA Driver)

Base Software Used:
NVidia Purevideo Decoder (formally DVD Decoder)
GBPVR v0.98.8
MS-DVR Mux

Though this I've learned a few things about ATSC and the setup above that I think will help everyone trying to get HD working (and working well) with their GBPVR setup.

Setting it up
1. Running v0.98.8
If your running v0.98.8 download the patches sub has put out at http://www.gbpvr.com/atsc-scan5.zip - This corrected my tuning (and many others) problem.

2. Decoding the HD signal requires a GOOD MPEG2 video decoder.

The Geforce 5200 (and above) models have hardware based decoding on the GPU. You can buy a 5200 card for $30 and because of the GPU the Purvideo decoder then offloads this from your CPU. When recording, and playing back under this scenario, I usually run around 60% CPU. 58% of that is the playback only 2% is recording.

I found that the Cyberlink decoder didn't do as good of a job. It used more CPU and couldn't take advantage of the GPU.

Don't be surprised if your video ends up choppy if you're running at near 100% CPU.

3. Mux settings.

Once again cyberlink mux didn't work as well as MS-DVR. Several threads here indicate that MS-DVR is the way to go, I agree. I get much better mileage from MS-DVR than .MPEG using cyberlink.

4. Antenna

I ran into some problems which I thought were hardware or GBPVR based with tuning. The fact of the matter is that this has a HUGE impact on your ability to get good HD signal. Some of this applies to general HDTV viewing not just recording. If you're serious about your setup there are 2 pages I suggest reading.

http://www.tvtower.com/hdtv_antenna_and_reception.html is written by a former Assistant Chief Engineer at a television station. This outlines that you shouldn't be using an amplifier as it can really hurt your signal. It also addresses issues in HDTV signal that many people may relate to GBPVR but are actually signal problems (as in my case). Skips, and choppy video can be interference not GBPVR, your Decoder or your CPU. This by far corrected many of my ATSC Tuner problems.

http://www.antennaweb.org/aw/welcome.aspx is a great site for tuning up your HDTV antenna. This allows you to actually adjust it for the direction and location you are at. Great information. This alone increased my reception by pointing in the most accurate direction.

If you have issues with "Choppy video", "Pixilization" and "Gaps in recording" it may be your antenna setup. Even though your "TV" may have good reception, I have found that tuner cards don't employ the same quality in signal filtering that a good TV will.

Recordings

1. Make sure you have drive space!

Recording in my area usually range around 6.7GB per hour (HD Quality). This can quickly eat up a hard drive. Be prepared to delete recordings when you are done.

2. SD takes up less space

Know which channels are transmitting in SD. If you record SD it's considerably less space than HD.

3. Defragment

If you don't defrag your drive and you record often, you can see issues with recordings.
http://www.compu-docs.com/W2KDfrag.htm is a great article on scheduling defragmentation at "off hours". Pick a good time when they are running infomercials!


Hope this helps someone I've got a lot of hours tied up getting this running. You can get HD for less money!

Friday, September 15, 2006

VFP: User interface not allowed at this time

While trying to use a foxpro COM object in .NET for a project I'm working on I ran into this little problem.



VFP: User interface not allowed at this time



Intresting enough it makes sense. The .DLL by law cannot have interfaces to it. VFP 6 at least doesnt suppress this when it compiles a DLL. I don't know about future versions such as 9 installed on my machine, but our production code is stuck in 6.0 for the moment.



The easiest work around for this was to compile it as a COM EXE server. This allows for the wait windows to show up in the upper right of the machine on the desktop window.



Which is a very intresting point. I'm quite surprised that the same EXE that you compile for any other foxpro application can also act as a com server. Simply exposing the class via OLE PUBLIC specification seems to be more than enough to use any EXE as a COM server and allow another application to use that server.



While I can use the work around, I don't really agree with it. VFP should have supressed the calls to the WAIT WINDOW in the DLL Compile and compeltely ignored that output. I can see if I was making a MESSAGEBOX call, but with a wait window it should have just been surpressed. Ultimately I'd remove the wait windows and make it a true DLL but I'd have to bust open too much legacy code.



On the other side of things, one additional note about this project. When using a COM object made in foxpro from within .NET, make sure youre cleaning up your objects. As anyone who's used foxpro for any great amount of time knows, it makes for lazy programmers. V ariables are often not cleaned up . Foxpro doesnt care and thus you can get some unpredictable results as part of you com object use.



I suggest that you use the .NET System.Runtime.InteropServices and call the Marshall.ReleaseComObject() at the end of each call to you com object. You can avoid this by writing really good foxpro code, but few people do that.

Wednesday, May 17, 2006

VFP: Inserting Nodes with XML Object

This was not a fun experiment. The key here is that we are using Visual Foxpro
to insert into a XML document. We do this by selecting the parent node, then insert
into the child nodes at a specific location. I dont see any other way to optimize this but I'm open for suggestions.





* OPEN MSXML Object
xmlDoc=CREATEOBJECT("Msxml2.DOMDocument.6.0")
xmlDoc.ASYNC="false"
xmlDoc.LOAD("xmltest.xml")
x=xmlDoc.documentElement

* INit document fragment
docFrag = xmlDoc.CreateDocumentFragment()

* Set the XML
docFrag.appendChild(xmlDoc.CreateElement("REF_J"))

* Obtain Original Node where children Exist
oNode=xmlDoc.selectnodes("/recordset/L.2000B/L.2300")
i=0
* Object Creation Of children nodes to iterate
objChildNodes = oNode.ITEM(0).childNodes
* Iterate through children, identify the node you want to insert before
FOR EACH strNode IN objChildNodes
** NODE IDENTIFIED, DO INSERT
IF strNode.nodename="REF_K"
* Inserting at the location of the node with children, insert before the location of the child node.
oNode.ITEM(0).insertBefore(docFrag, oNode.ITEM(0).childNodes.ITEM(i))
EXIT FOR
ENDIF
i=i+1
NEXT

* Save XML
xmlDoc.SAVE("xmltest-output.xml")


Monday, May 15, 2006

Linux: Dell Latitude LM, XWindows, Neomagic Magicgraph

I have to be the first to say that it's always a challenge working with older hardware. I recently received a Dell Latitude LM Laptop which is only a P133 with an 800x600x256 display adapter (Neomagic 2070 (NM2070)). The only thing magical about this was it's ability to not run X on it properly. I had serious display issues from the start. I was able to get VGA to run on it, but who can surf the web at 640x480. It looked terrible.


I was able to get it working through some serious troubleshooting over several hours. The DEFAULT Debain package configuration WILL NOT get you to a working mode with this hardware.


I added 2 options to my XF86Config which did make it work. Now I dont know which one for sure did the trick, but it seems to be running great now.


All Debian Packages in "stable"



Option "NoAccel" "True"


This turns off the acceleration on the card. I think this is probably the option that fixed the problem.

Thursday, April 27, 2006

CIO Blogs - Could "Found Code" Cripple Your Company? |

While the article
CIO Blogs - Could "Found Code" Cripple Your Company? | makes some valid points, what they don't mention is the impact of not using these types of resources. When you ask most developers what they do when they hit a wall on a problem they almost always say "Go to the web". Frankly, it's what the damn thing was invented for anyhow.



Management is often unwilling to hear (or accept) how long something will really take to develop. The other side of it is that many developers lack the skill to develop the same piece of code. This is not a fault of the hiring process or the developer, it's just a fact. Developers in many cases are like doctors, some work in the general field of coding, some are specialized surgeons. You wont find a developer that knows everything, just too much out there.



I think the mind set of management is what needs to change here. I think that reasonable and acceptable use of searched code could be used in most environments. Most developers (who develop for GPL projects) generally don't have an issue with someone using their brilliant code somewhere else. The problem is if they want to sell it. Most companies that develop software do it for internal purposes vs. producing a software product they outright sell. Blackberry comes to mind where "sold for profit" bit them in the ass. If blackberry was using the same type of code in their accounting software, nobody would have known, or cared. Developing an "acceptable use" policy would be a preferred method for handling this type of issue vs. overreacting and saying "don't use it". With that sort of policy you'd end up extending deadlines and your developers would adopt a "don't ask, don't tell" policy.

Monday, April 24, 2006

TechToolBlog 195 Free Online Programming Books

Well this was cool. Where else can you find 195 books on programming. Some of the basics are in here. Hey, what can you really expect for free.



TechToolBlog � 195 Free Online Programming Books - Web Programming focusing on Marketing the world wide web

Convert String to Byte Array

Thanks dave, this is a great piece of code however more blog entries showed there was a flaw (at least for my milage). Saved me some time though. Why microsoft doesnt have this natively in the .net framework is also beyond me. The sample below is my slightly modified version which does do the conversion correctly.

Imports System.Text  Public Shared Function ConvertStringToByteArray(ByVal stringToConvert As String) As Byte()     Return System.Text.Encoding.ASCII.GetBytes(stringToConvert.ToCharArray()) End Function


Convert String to Byte Array

Sql Server Row Size Limit - Rick Strahl's WebLog

Sql Server Row Size Limit - Rick Strahl's WebLog

Did you know that SQL server had an 8K row limit? I didn't either until Michele ran into the problem and I started researching it. What a load of crap. Thanks Microsoft.

Friday, April 21, 2006

Visual Studio Express

Microsoft has made Visual Studio Express completely free permanantly. Their FAQ now states


10. How much will these products cost?
Effective April 19th, 2006, all Visual Studio 2005 Express Editions are free permanently. This pricing covers all Visual Studio 2005 Express Editions including Visual Basic, Visual C#, Visual C++, Visual J#, and Visual Web Developer as well as all localized versions of Visual Studio Express.

SQL Server 2005 Express Edition has always been and will continue to be a free download.

I can't help but think that this was all forged by the GNU project and FSF with years of free software.

VB.NET: Base 36 Function

My office frequently uses BASE36 for naming of transactions and files. This is a base36 function in VB.NET. Simply passing in the integer will return the BASE36 value for it. I wrote this function as I was not aware of any way to natively do this in .NET. I have searched the net high and low for something like this but wasnt able to find one. Hopefully somone else will make use of it.



include_once('/home/rwmech/public_html/robsprogrammingjunk/geshi/geshi.php');

$source = <<
Private Function Base36(ByVal intNumber As Int32) As String
Dim intNum As Int32
Dim strSum As String
Dim intCarry As Int32
Dim intConvertBase As Int32 = 36
strSum = ""
intNum = intNumber
Do
intCarry = intNum Mod intConvertBase
If intCarry > 9 Then
strSum = Chr(intCarry + 87) + strSum
Else
strSum = intCarry & strSum
End If
intNum = Int(intNum / intConvertBase)
Loop Until intNum = 0
Return strSum
End Function

END;

$geshi = new GeSHi($source, 'vbnet');
$geshi->set_header_type(GESHI_HEADER_DIV);
$geshi->set_overall_style('font-family: Courier New , Courier, Monospace; font-size: 8pt; word-wrap:break-word;');
$geshi->set_comments_style(1, 'color: #006600;');
$geshi->set_comments_style('MULTI', 'color: #006600;');
$geshi->set_header_content('Code Example © Robert Mech. May be used freely as long as credit is given to the source.');
$geshi->set_header_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
$geshi->set_footer_content('If you use this code, please make a comment on the blog!');
$geshi->set_footer_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');

echo $geshi->parse_code();
?>

BLOGGER: You can use GeSHi in your blogger posts

You can use GeSHi in your blogger posts. Simply use your own PHP server and install GeSHi. Then you can use the following code to post code snippets to your blog.



A few notes:

1. You must tell blogger to not convert your line breaks. If you don't it'll screw up the PHP code.

2. You must have your blogger set to create an index.php or the like.

3. Change the 'php' below to the proper language based on what you're posting.




Code Example © Robert Mech. May be used freely as long as credit is given to the source.





<?php
include_once('geshi/geshi.php');



$source = <<<END



// SOURCE CODE HERE



END;



$geshi = new GeSHi($source, 'php');

$geshi->set_header_type(GESHI_HEADER_DIV);



echo $geshi->parse_code();


?>


If you use this code, please make a comment on the blog!


LINUX: wget

I'm always forgetting this command and it's very useful for getting downloads to you linux box quickly.
 
Usage: wget [OPTION]... [URL]...
 

Thursday, April 20, 2006

FOXPRO: Defeat the error handler

include_once('geshi/geshi.php');

$source = <<
ON ERROR *

END;

$geshi = new GeSHi($source, 'visualfoxpro');
$geshi->set_header_type(GESHI_HEADER_DIV);
$geshi->set_overall_style('font-family: Courier New , Courier, Monospace; font-size: 8pt; word-wrap:break-word;');
$geshi->set_comments_style(1, 'color: #006600;');
$geshi->set_comments_style('MULTI', 'color: #006600;');
$geshi->set_header_content('Code Example © Robert Mech. May be used freely as long as credit is given to the source.');
$geshi->set_header_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
$geshi->set_footer_content('If you use this code, please make a comment on the blog!');
$geshi->set_footer_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');

echo $geshi->parse_code();
?>

 
This disables the fox error handler.  It fixes just about everything. :)

Wednesday, April 19, 2006

ALL: MSXML Memory Leaks

I recently ran into a problem with MSXML and memory leaks.  If you repeatedly call it from within FoxPro with many SelectNodes() in there you'll certainly run into a problem.  Go with the MSXML6 or higher where it doesn't have nearly as many memory leaks.  It's documented on MSDN, but was not easy to find.  http://support.microsoft.com/kb/328998 

Monday, March 20, 2006

FOXPRO: Connection Pooling Sucks

Connection pooling can really suck when you're not using SQL server or another client/server based SQL. Take foxpro for example. Connection polling in OLEDB can keep a table "open" long after you've cleared references to it. This means that if you want the table exclusive later on you wont be able to because of the reference. I discovered this when I needed to physically delete a table that I had opened and read the information from



Dim strConnString = "Driver={Microsoft Visual Foxpro Driver};SourceType=DBF;SourceDB=C:\DBFDIRECTORY;Uid=;Pwd=;OLE DB Services=-4;"


The sample above shows that OLE DB Services=-4 will turn off that connection pooling on foxpro and close the table when you actually request it. There is some small performance hit here, but nothing to hollar about considering youre using foxpro anyhow. :)

Wednesday, March 15, 2006

VB.NET: SMTP Mail

Easy SMTP function in VB.NET


Imports System.Web.Mail.SmtpMail
Imports System.Data
Imports System.Data.SqlClient

Function SendEmail(ByVal strTo As String, ByVal strFrom As String, ByVal strBody As String, ByVal strSubject As String, Optional ByVal strCC As String = "") As Boolean
Dim email As New System.Web.Mail.MailMessage()
email.To = strTo
email.Cc = strCC
email.From = strFrom
email.Body = strBody
email.Subject = strSubject
email.BodyFormat = Web.Mail.MailFormat.Text
Try
System.Web.Mail.SmtpMail.SmtpServer = "primaryserver.com"
System.Web.Mail.SmtpMail.Send(email)
Catch e As Exception
Debug.WriteLine(e)
email.Body = strBody & vbCrLf & vbCrLf & "MAIN SMTP SERVER ERROR: " & vbCrLf & e.ToString
System.Web.Mail.SmtpMail.SmtpServer = "secondary server.com"
System.Web.Mail.SmtpMail.Send(email)
End Try
Return True
End Function

Tuesday, March 14, 2006

VB.NET: Strong Naming

Quick and ditry strong naming. Very helpful for no longer having to trust assemblys on a network.

Execute:

sn.exe -k PublicPrivateKeyFile.snk




'Strong Naming
<Assembly: System.Reflection.AssemblyDelaySign(False)>
<Assembly: System.Reflection.AssemblyKeyFile("mailpost.sn")>


One more note here, 1.0 looks in the current directory. 1.1 requires a full path to th key.

Monday, March 13, 2006

VB.NET: Formatting for bytes with commas

Formatting for bytes with commas. For example 1,000 or 1,000,000. While this is really basic, I almost always forget this.

include_once('/home/rwmech/public_html/robsprogrammingjunk/geshi/geshi.php');

$source = <<'To format a number with commas
Format(intBytesProc, "#,##0")

END;

$geshi = new GeSHi($source, 'vbnet');
$geshi->set_header_type(GESHI_HEADER_DIV);
$geshi->set_overall_style('font-family: Courier New , Courier, Monospace; font-size: 8pt; word-wrap:break-word;');
$geshi->set_comments_style(1, 'color: #006600;');
$geshi->set_comments_style('MULTI', 'color: #006600;');
$geshi->set_header_content('Code Example © Robert Mech. May be used freely as long as credit is given to the source.');
$geshi->set_header_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
$geshi->set_footer_content('If you use this code, please make a comment on the blog!');
$geshi->set_footer_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');

echo $geshi->parse_code();
?>

Wednesday, February 08, 2006

FOXPRO: Using a filesystem object instead of ADIR()

ADIR() is a very bad thing. Large directories are very very slow to read and can even crash with TOO MANY VARIABLES because of the foxpro array limitation. This snippet allows me to get around that.



include_once('/home/rwmech/public_html/robsprogrammingjunk/geshi/geshi.php');

$source = <<
loFSO=CREATEOBJECT('Scripting.FileSystemObject')
lsDrive=SYS(5)
loFolders=loFSO.GetFolder(lsDrive+'\\\somefolder')
FOR EACH loSomeFolder IN loFolders.Subfolders
IF !FILE(lsDrive+'\\\somefolder\\\'+ALLT(loSomeFolder.NAME))
WAIT WINDOW 'Checking '+ lsDrive+'\\\somefolder\\\'+ALLT(loSomeFolder.NAME) NOWAIT
FOR EACH loFile IN loSomeFolder.FILES
* DO SOMEHTING WITH THE FILE
* lsDrive+'\\\somefolder\\\'+ allt(loSomeFolder.Name)+'\\\'+allt(loFile.Name)
ENDFOR
ENDIF
ENDFOR
RELEASE loFolders
RELEASE loFile
RELEASE loFSO
WAIT CLEAR


END;

$geshi = new GeSHi($source, 'visualfoxpro');
$geshi->set_header_type(GESHI_HEADER_DIV);
$geshi->set_overall_style('font-family: Courier New , Courier, Monospace; font-size: 8pt; word-wrap:break-word;');
$geshi->set_comments_style(1, 'color: #006600;');
$geshi->set_comments_style('MULTI', 'color: #006600;');
$geshi->set_header_content('Code Example © Robert Mech. May be used freely as long as credit is given to the source.');
$geshi->set_header_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
$geshi->set_footer_content('If you use this code, please make a comment on the blog!');
$geshi->set_footer_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');

echo $geshi->parse_code();
?>