Saturday, September 15, 2012

Reseed Identity Using Variable

In a sproc that involves creating a copy of a production SQL table for testing, I wanted to reseed the identity of the new table to 1 more than the max of the production key value. 

I figured at first I'd just use the appropriate syntax for DBCC and just use a variable already at hand containing the max production value and add 1 to it, like so:

 DECLARE @MaxID int

 -- Grab the max identity value from production.
 SELECT @MaxID = MAX(ID) FROM dbo.MyProductionTable

 DBCC CHECKIDENT (MyProductionTable_COPY, reseed, @MaxID + 1) 


SQL, however, would have nothing of it:
Incorrect syntax near '+'.

To work around this, I decided to try creating a dynamic SQL string to incorporate the variable arithmetic:

 DECLARE @MaxID int
 DECLARE @SQL nvarchar(100)

 -- Grab the max identity value from production.
 SELECT @MaxID = MAX(ID) FROM dbo.MyProductionTable

 SET @SQL = 'DBCC CHECKIDENT (MyProductionTable_COPY, reseed, ' 
 + CAST(@MaxID + 1 AS nvarchar(10)) 
 + ')'


Now I can create the table and set its starting identity value to 1 greater than in production using a variable despite DBCC's syntax dictating otherwise.





Friday, August 31, 2012

Enforced Dependencies and Schemabinding

In trying to rename a table I encountered the dreaded error about enforced dependencies:
Object 'myTable' cannot be renamed because the object participates in enforced dependencies.

I first used the following script to identify the objects dependent upon the table:
SELECT DISTINCT o.object_id, o.name, o.type_desc, m.definition
FROM sys.sql_dependencies d
JOIN sys.objects o ON o.object_id = d.object_id
JOIN sys.objects r ON r.object_id = d.referenced_major_id
JOIN sys.sql_modules m ON m.object_id = o.object_id
WHERE d.class = 1
AND r.name = 'myTable'

This yielded the names of three objects in my database which happen to use SCHEMABINDING in their definitions.

I didn't want to manually alter and recreate these objects, so instead I decided to create a script which will find the SQL code for each object, remove the WITH SCHEMABINDING syntax, drop the existing objects and then recreate them sans schema binding.

DECLARE
     @TheTable varchar(100),

     @Count int,
     @Max int,

     @object_id int,
     @name varchar(50),
     @type_desc varchar(50),
     @definition nvarchar(max),
 
     @DropSQL nvarchar(max),
     @CreateSQL nvarchar(max)

-- Remove schemabinding from objects tied to table.
DECLARE @Objects TABLE
(
     ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
     object_id int,
     name varchar(50),
     type_desc varchar(50),
     definition nvarchar(max)
)

-- Set the table name here:
SET @TheTable = 'MyTable'

INSERT INTO @Objects (object_id, name, type_desc, definition)
SELECT DISTINCT o.object_id, o.name, o.type_desc, m.definition
FROM sys.sql_dependencies d
JOIN sys.objects o ON o.object_id = d.object_id
JOIN sys.objects r ON r.object_id = d.referenced_major_id
JOIN sys.sql_modules m ON m.object_id = o.object_id
WHERE d.class = 1
AND r.name = @TheTable

UPDATE @Objects
SET definition = 
     CASE
          WHEN definition LIKE '%SCHEMABINDING%' THEN REPLACE(definition, 'WITH SCHEMABINDING', '')
          ELSE definition
     END


SELECT @Count = 1, @Max = COUNT(ID) FROM @Objects

WHILE @Count <= @Max
BEGIN

     SELECT @object_id = object_id, @name = name, @type_desc = type_desc, @definition = definition
     FROM @Objects
     WHERE ID = @Count

     SET @DropSQL =   'DROP ' 
     +
     CASE @type_desc 
          WHEN 'VIEW' THEN 'VIEW'
          WHEN 'SQL_SCALAR_FUNCTION' THEN 'FUNCTION'
          WHEN 'SQL_TABLE_VALUED_FUNCTION' THEN 'FUNCTION'
          WHEN 'SQL_STORED_PROCEDURE' THEN 'PROCEDURE'
          WHEN 'SQL_TRIGGER' THEN 'TRIGGER'
     END
     +
     ' '
     + 
     @name

     PRINT @DropSQL
     EXEC sp_executeSQL @DropSQL

     SET @CreateSQL = @definition

     PRINT @CreateSQL
     EXEC sp_executeSQL @CreateSQL

     SET @Count = @Count + 1

END


Now I can incorporate this logic into a sproc and not have to worry about meddlesome constraints if I'm going to be renaming tables. The above script has been tested successfully under SQL 2008 and 2012, and will be able to automatically drop and recreate views, scalar and table valued functions, sprocs and triggers.






 

Friday, August 24, 2012

Monday, August 20, 2012

Those Bitches!

Classic scene I captured in animated GIF form in homage to the hilarious parody trailer, Star Wars Episode III: A Lost Hope.


Photoshop CS5 Slow Animated GIF Playback

In Photoshop CS5 you can import video and transform it into a series of layers, then export that collection of layers as an animated GIF.

However, one gotcha I encountered has to do with frame rate and playback speed of the resulting GIF animation. I found that despite the fact that I'd set the no delay between each frame, the animation appeared slow regardless of which browser I used.

To work around this annoyance, I found that I needed to tweak the frame rate of the animation in timeline mode. 

Here's how.

First off, make sure the QuickTime player is installed. Photoshop uses QuickTime to render video into layers, and the video must be viewable in QuickTime in order to be imported properly; if it's not and using some unrecognized video codec, it might import as a series of blank frames.

In Windows Explorer, right-click on the video file you want to import, and click the Details tab. Note the frame rate of the video in question is 25 frames per second (fps).




Click File => Import => Video Frames to Layers and import your video into Photoshop.

In Photoshop, perform edits you want, such as removing frames, adding text, whatever you need to do for your animation.

Ensure the Animation panel is visible by clicking Window and verifying a checkmark is beside Animation. Then, click on the button in the lower-right area of the frame view, which has a tooltip "Convert to timeline animation". Upon doing this, the frame view will disappear and be replaced with a timeline showing the layers stacked upon each other.



You should also notice that in the timeline view, the frame rate is shown. Note how it differs from the original frame rate of the imported video.



Now we alter the animation's frame rate to correspond to the original video's frame rate. In the upper-right corner of the Animation panel you should see a tiny upside-down triangle. Click this to reveal the Animation panel's popup menu, then click Document Settings.




Now the Document Timeline Settings window appears, from which you can change the Frame Rate from the default of 30 to the value corresponding to that of your imported video, in this case, 25.




Finally, click File => Save for Web & Devices to save the project as an animated GIF according to the settings you require. The resulting GIF should now be in sync with the original video in terms of frame rate, and render at about the same speed rather than annoyingly slow.




Friday, August 10, 2012

Mitt Romney's Wild Ride


Friday, July 27, 2012

Gee thanks, South Park!

Oh South Park, you think you couldn't drop a deuce on the English language for unsuspecting citizens?? Well, think again! As this clip from the episode Margaritaville demonstrates, you've succeeded in corrupting thousands of minds, making them pure as the driven-through snow!  

From the episode...



















Sunday, July 1, 2012

Sunday, June 10, 2012

Free Credit Report

A good credit score is important for securing loans or incurring other types of debt.

According to the Federal Trade Commission, the Fair Credit Reporting Act includes a provision whereby the big three credit reporting companies (Equifax, TransUnion, and Experian) must provide you, free of charge, a copy of your credit report annually.

The easiest way to get the ball rolling is to visit the official site, AnnualCreditReport.com, and fill out their form. 




Eventually you'll be forwarded to each credit reporting site, in turn, to input some answers to security questions. Then you can either view your report online, or download it in PDF form. You can also view the report in printer-friendly format, then use a free utility like Cute PDF Writer to "print" the report to a PDF file.

I had no idea one could obtain a completely FREE report of your credit history from the big three companies in this way, so score one for government working for the people.




Friday, June 1, 2012

Obtain Element Coordinates Using JQuery

I'm working on a project with ASP.NET and JQuery where I need to be able to obtain the coordinates for a div element in response to a button click. I found an example here, but I wanted to get not just the top and left values, but be able to obtain coordinates of all four corners.

To do this, I make use of JQuery's position, height, and width functions, then simply use some arithmetic to obtain the coordinates and finally display them. 

Here's an example. First, the markup:
<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

Div Coordinates





I am a div.

Now, the code behind: 

protected void Button1_Click(object sender, EventArgs e)
{
     Label1.Text = "Top Left: " + hfTop.Value + ", " + hfLeft.Value;
     Label2.Text = "Top Right: " + hfTop.Value + ", " + hfRight.Value;
     Label3.Text = "Bottom Left: " + hfBottom.Value + ", " + hfLeft.Value;
     Label4.Text = "Bottom Right: " + hfBottom.Value + ", " + hfRight.Value;
}



In a nutshell, the button click first triggers the OnClientClick event, which calls the JQuery functions to populate the values of the HiddenField objects. Then, the OnClick method takes those values and concatenates them in the code behind into coordinate pairs to display as the label text.
In cases where we need specific coordinates of each corner of a div element in response to a click event, this method works nicely.



Wednesday, May 30, 2012

Firefox Performance Problems

Lately I've noticed Firefox seems to be lagging as of the latest release of version 12. 

Since my earlier post regarding setting Firefox up to utilize CPU affinity in Windows, things have been manageable, but lately a familiar flavor of failure seems to have crept back into this latest release.

If I leave Firefox open and running overnight with my usual group of a dozen or so tabs open, as soon as I resume activity in the morning, I notice in Task Manager that Firefox has one of my system's CPU cores at 100% usage, and has well over 1.7 GB of system memory in use, far more than what typically ranges from 400 to 700 MB on an average day.

Any given morning, thanks to Firefox.

More often than not, once I clear this CPU usage spike by ending the firefox.exe process, when I reopen Firefox I'm greeted with tabs notifying me of add-on updates that have been applied. 


This same issue seemed to be absent as of, say, version 10, but appears to have recently reemerged, at least in my experience on several different PCs running Windows 7.

A common thread among established users on the Firefox support forum points to the various add-ons users have installed. Clearly, many of them say, this is the culprit, and the often the user is advised to open Firefox sans add-ons and attempt to reproduce the problem by enabling add-ons one by one and testing after each to determine which might be the culprit.

I have no desire to invest the time and effort in something that I think developers and analysts at Mozilla should be hammering out themselves. It seems that if you release a platform on which users will develop add-ons, there should be safeguards in place to prevent poor coding from disrupting the integrity of the browser's functionality.

That being said, if you have a 64-bit system, consider trying out Waterfox, a Firefox build which emphasizes performance and speed, and mitigates a lot of whatever lurks in Firefox's codebase that might be causing this excessive memory usage and lag.

Perhaps it's some insidious conspiracy to make it so that when your computer is otherwise asleep at night, Firefox will rear its head and ramp up CPU usage and therefore power consumption, making an impact, however small, on world oil prices, driving up costs and compelling people to bite the bullet and get off the grid with their own solar, wind, nuclear, or other alternative power source.

I've had crazier ideas!




Saturday, May 12, 2012

Magnets, How They DO Work

Love bug season has descended unexpectedly early here in north central Florida.

Love bugs love lovin' at our expense.
 
Swarms of these annoying insects, male and female joined at the butt, fly adrift, ready albeit unwilling to let themselves be splattered at high speed against the finish of your car. Given time and accelerated by summer heat, their acidic gut chemistry can pit the paint and fill the delicate fins of your radiator with bug parts.



An easy, somewhat ghetto measure can be taken to protect the radiator and engine compartment from these annoying insects. All you need is some plastic screening material, a dead hard drive, and scissors.

I drive a minivan, so I don't much care about its finish, I'm more concerned about function than form. In my case, I just cut a swatch of plastic screening material large enough to cover the radiator openings in the front grille, then secured it at either top corner with a rare-earth magnet salvaged from a long-dead hard drive.



The few inches of overlap will allow the screen to stay draped over the grille openings while driving, as will the curve of the grille itself. A masochist might go so far as to have a wire mesh complete with some power running through it to act as a mobile bug zapper and decrease the bug population, but I lack the motivation and time to go that far, I'm content to just keep them out.

Now my engine can remain bug free, without compromising airflow the engine needs so that the radiator can dissipate heat on the road.


Friday, May 11, 2012

Inconsistent Line Ending Style

In trying to commit some changes to SVN using the TortoiseSVN client, I received an odd error for a single SQL database table script text file:

Inconsistent line ending style


On the TortoiseSVN forums someone suggested that this might have occurred because someone edited the file in multiple editors, and somewhere in the process happened to slip in a line feed particular to their editor which version 1.7.4 of our Apache Subversion server found disagreeable.

To work around this, I was able to open the file in Microsoft Word, then save the file as plain text, with Windows (Default) chosen for text encoding:



Why SVN server scrutinizes the line feeds is unclear to me, but thankfully whomever committed the offending change made it to just this one file out of hundreds in the repository.





Wednesday, April 11, 2012

Pick One Random Number from a Set of Numbers

A while back I posted a means to generate random numbers in SQL. I ran across a situation where I need to pick one number randomly from a set of numbers.

I found a decent solution here, but I didn't want to create a separate view and scalar function for this task.

Instead I create a table variable with a single integer column as the primary key. Next, I insert each of the values of the small set of numbers into the table variable. Finally, I perform a SELECT against the table variable with NEWID() specified in the ORDER BY clause, so that a randomly-chosen member of the set will be returned. 

        DECLARE @Code int

        DECLARE @Codes TABLE
        (
            Code int PRIMARY KEY
        )
       
        INSERT INTO @Codes (Code) VALUES (3)  
        INSERT INTO @Codes (Code) VALUES (6)
        INSERT INTO @Codes (Code) VALUES (9)
        INSERT INTO @Codes (Code) VALUES (12)

        IF @Code IS NULL
            SELECT TOP 1 @Code = Code FROM @Codes ORDER BY NEWID()

  
In my case this is to provide a stored procedure, which may or may not have a value provided for the @Code input parameter, be able to automatically pick a random value in case @Code is NULL. The table variable isn't necessary if the value being picked is among the primary key values of an existing table; a random selection can be obtained simply by doing a SELECT with NEWID().








Thursday, March 22, 2012

Disclaimer

All data and information provided on this site is for informational purposes only. 

DarthContinent.com makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this site and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.

There, now that the legal mumbo jumbo is out of the way, to put it more succinctly, read this at your own risk. I absolutely will not be responsible for any misuse of information contained wherein which happens to be detrimental to the well being of yourself, your Facebook friends, your in-laws, nor anyone else in the whole world, in perpetuity. 

Even the Jedi have no sway here! 

They, too, are bound by galactic law, despite their deep desire to eradicate the Sith. Indeed, were the Jedi to attempt to take this site down by Force, figuratively or literally, I would use the Sith powers at my disposal to squish their testicles or ovaries into raisin-like remnants of their former glory! Then would they know the TRUE power of the Force and the Dark side!

Well. Enough of that, let's party!






Friday, February 10, 2012

Freaky Friday, Reddit Style

Not like this, Reddit. Not like this. Once again, the Reddit-headed step child appears to be looming as inexplicably comments have ceased to be visible as of around 10:30 am EST.


Have the admins tapped a keg early? Has a lowly intern been given the keys to admin access enabling them to wreak havoc upon the database?? Who knows. Perhaps Reddit needs a makeover.


 

Thursday, February 2, 2012

Cents and Sensibility

I recently received a check in the mail for the eBay vs Yingling class-action lawsuit.















This makes no cents whatsoever.




Friday, January 20, 2012

DD-WRT Port Forwarding Problems

Recently I bought a Buffalo WZR-HP-G300NH wireless router accompanied with a branded version of the popular third-party linux-based firmware DD-WRT to replace my previous router, also a Buffalo but an older model, the WHR-HP-G54
Buffalo WZR-HP-G300NH2, my soon-to-be-nemesis.

My old router ran rock solid for 5+ years' worth of torrenting and wireless and innumerable bits of data transfer until inexplicably one day a power surge appeared to have killed the wireless. Wireless is too handy not to have, so I bid my venerable router farewell. I figured this also would be the opportunity to do something I hadn't tried in some time, host a web server on my local machine. My ISP doesn't block port 80, so I figured I could pretty easily set up port forwarding and invite some folks to test out a site I've been developing.

I began by setting up Port Forwarding for TCP port 80 to my computer's IP address on my LAN in DD-WRT. I also used DynDNS to redirect a custom public URL to the dynamic IP address assigned by my ISP. Curiously, after rebooting the router, for some reason port 80 traffic returned "The connection has timed out" in Firefox, not only when I tried to hit the URL from a remote session to a computer at my office, but even using that same URL or even the local IP address on my own LAN. 

To rule out the possibility of my ISP blocking port 80 traffic, I tried setting up a spare Linksys WRTG54 v6 router I had lying around, using its factory firmware to set up a port forwarding rule. This worked fine, so clearly my ISP was not to blame. Indeed, a visit to CanYouSeeMe confirmed that port 80 was closed off to the outside world.

Undaunted, I decided to upgrade to the newest firmware from the manufacturer's support site. Buffalo seems to have had a bit of a disconnect with their product labeling. Whereas I thought I'd ordered the WZR-HP-G300NH, the model number on the router itself indicated it was actually a WZR-HP-G300NH2, which turns out to have different internals. The product dropdown list indicated two flavors of this particular router, both indicating WZR-HP-G300NH, and to the far right, one indicated as v1, the other v2.





This in itself was no big deal until I tried updating to the latest available firmware from Buffalo's support site. I assumed WZR-HP-G300NH2 corresponded to the entry for WZR-HP-G300NH v2, and chose the firmware accordingly. I proceeded to update the firmware via DD-WRT installed at the factory, and even got a message that the update went successfully and that the router commenced a reboot. Minutes passed, the DIAG light on the router flashing for a while, at first, but then ominously steady.


I left it for an hour to grab something to eat. When I returned, the steady DIAG stared me in the face. I went ahead and cycled power on the router, and the DIAG again stayed steady. Worse, the router's DHCP appeared dead, leaving Windows to assign the default IP via its APIPA, a fallback in case the router doesn't give out an IP address dynamically. The router didn't even respond when I assigned a static IP in its default subnet.

My shiny new router became officially bricked.




I managed to unbrick the router thanks to this blog post and at least install a compatible build of DD-WRT contributed by Brainslayer, a DD-WRT forum user, located on the DD-WRT FTP site here

Incidentally, the DD-WRT Router Database is currently clueless about the existence of the G300NH2 version of the router; the "official" build of DD-WRT I downloaded on the off chance it might work (wzr-hp-g300nh-dd-wrt-webupgrade-MULTI.bin) upgraded fine, according to the DD-WRT web interface, but the router bricked shortly after rebooting without any message indicating failure. Attempting to use this same build to upgrade via TFTP returned "Unsupport MODEL." which seems to indicate that the GUI overlooked the crucial problem with trying to apply a firmware that the router's most basic boot code recognized as an incompatible version... but I digress!

I then researched port forwarding issues and posted details to the DD-WRT forums as well as ServerFault, and although I was able to fix the issue with port forwarding failing from a computer on the LAN thanks to a workaround posted on the forums, no matter what DD-WRT build I tried, external port forwarding failed.

After literally dozens of attempts to reflash the firmware with various builds of DD-WRT, searching for alternative firmwares like Tomato and HyperWRT only to find that they support the G300NH, not the G300NH2, I finally settled on OpenWRT. They, at least, have a wiki specific to the v2 version of the router, albeit one that doesn't appear toward the top of the search results. I also found a wiki for the v1 model, riddled with warnings about the mysterious hardware discrepancies between the v1 and v2 models, interspersed with various "fix me" tags which didn't bode well.

Fix Me? Warning?? Super.

Unfortunately, a big disappointment for me was OpenWRT's lack of a native web interface. I've used Linux so that's not so much of a problem, it's just more scripting and typing that I'd rather relegate to a web interface designed for the job. DD-WRT is leaps and bounds ahead of OpenWRT as far as its web interface is concerned.

Nevertheless, I found a separate web interface for OpenWRT named LuCI. I used the same TFTP method I'd utilized to unbrick the router to install OpenWRT itself, then proceeded to download and install LuCI. This seemingly simple process caused tremendous grief for several reasons, mainly through inconsistent documentation and aggravatingly terse responses to questions in myriad forum posts.

Case in point, I encountered numerous forum postings where someone reasonable familiar with Linux tries following steps outlined in the wiki to install the firmware and the web interface, but encounters a build error. All too often, the expert response to this conundrum essentially was "just do it this way" or "that's what you get for doing x instead of y".

Questions came to mind. Do what which way? How should I try what you're suggesting? What the hell is the context of this task with which you are intimately familiar, but which I, a mere Linux tourist, am unaware of? Those aren't the kind of replies that facilitate a satisfactory resolution of a problem. At best they're static, at worst they're a brush-off by someone who thinks they're doing you a tremendous service by graciously responding to your plea for advice with a few vague words.

As of now, my once bricked router is successfully running OpenWRT with LuCI. BONUS, port forwarding works!

From LuCI, clicking on Network => Firewall and then the Add button under the Redirections section lets you set up a forwarding rule. OpenWRT with LuCI may not win in the intuitive web interface department, but that's far less important than being able to freakin' port foward!



Problem solved, and thus ends a journey down a road I hope to never take again. If somehow I'm stuck having to go this route (pun intended) once again, I'm taking this router out back and crushing it to dust with a sledgehammer (its potential replacement is already en route from NewEgg just in case).






Wednesday, January 18, 2012

Blackout, or Blackmail?

Today, Wikipedia joins a host of other sites participating in a protest against SOPA and PIPA, legislation which threatens to cripple the internet as we know it.

In solidarity with this movement, a "blackout" page appears when you try to view a given Wikipedia article.



This is a token gesture at best, meant to prevent the majority of netizens from browsing their content. It's trivial to set up a rule in the Element HIding Helper for AdBlock Plus which prevents this banner from appearing in Firefox.

Here's how to view Wikipedia articles despite the blackout:

1. Tap the Alt key to view the menu in Firefox.

2. Click Tools => AdBlock Plus => Filter Preferences.



3. Add the following element hiding rule:
||wikipedia.org/w/index.php?title=Special:BannerController

As a longtime geek and software developer, it only took minutes for me to find a way around the blackout. It's easy to take for granted the ease of access we all have to vast
stores of information on the web. 

My first reaction to the blackout made me think blackmail

Here we have Wikipedia essentially holding their information hostage, allowing a relatively small minority with the skills and wherewithal to work around the block, while the rest scrabble around looking for other sites with information they need, or... gasp... going outside and walking to the public library to interact with a real, living human being to do their research.

For the duration of Wikipedia's blackout, there may be some who will suffer, albeit on the level of many relatively trivial first-world problems. Students scrambling to finish their research paper due later today will have to make do with various other sites that tell you about alternatives or help you work around the block. Someone looking up the etymology of mango for trivia with friends over lunch will have to look past the first or second search engine result.

Yet, it is sobering to think how much people will suffer should SOPA in its initially proposed form pass. Freedom of information is core to the internet and fundamental to the continually evolving paradigm introduced by the information age. Clearly SOPA threatens that liquidity of information and, in fairly typical form, reveals how ignorant politicians succumb to the swansong of SOPA supporters trying the latest shotgun approach in a weak effort to combat theft of intellectual property.

I'm happy to share information which will enable others to freely view Wikipedia despite the blackout, but in retrospect perhaps Wikipedia realized how easy it would be to work around the block, and get others at a similar place in life as myself to think for a moment about what it might be like for the rich Persian rug of information to be swept out from under our feet with the fall of a gavel in Congress.







Monday, January 2, 2012

Update DNS on NameCheap for Blogger

Having recently swapped my domain over from GoDaddy to NameCheap (using the latter's BYEBYEGD coupon for a bit of a discount), I needed to update my domain configuration on NameCheap with the proper A and CNAME records for Blogger to link to my domain name.

Google provides info on how to create a CNAME record for a custom domain for several registrars, GoDaddy among them, but NameCheap's configuration was less than intuitive to find and update.

I found it from My Account > Manage Domains > Modify Domain, and then under Host Management clicked All Host Records. Then I applied the info in the Google help page to my domain configuration:
 

Tuesday, December 13, 2011

The Family Dog


Tuesday, December 6, 2011

How to Spam Effectively

Here are some techniques on how to spam effectively.
  • Introduce yourself like you know the recipient personally. You might have some tender words in your subject line ("dearest", "beloved", "darling", "monkey love") which will immediately appeal to the reader and encourage them to check the message.
  • Pretend you're with a government agency or corporation. Believe me, when someone sees a message incoming from the FBI, CIA, Homeland Security, Bank of America, Hormel, Adam & Eve, or even The White House, it is a real attention getter!
  • Only use a first name in the "from" field of your messages. I have friends named Claire, Jane, Lexus, Chiquita, all of whom happen to be females with smokin' hot bodies. Of course I will not hesitate to open emails from these lovelies!
  • Use a free email provider like Yahoo to send out your messages. Using official addresses is so formal! Use casual addresses instead (like vincentnobi1970@yahoo.com) and you will instantly appeal to the recipient's heart and wallet.
  • Mention the name of a famous prescription drug, like Viagra. There is a flat 50% chance that the person reading your message has a penis. Use that opportunity to pimp the most effective erectile dysfunction drug in the world!
  • Occasionally misspell words, especially when impersonating a bank. Email can be so boring, everyone has a spellchecker these days. Be different! Tell someone they're going to loose access to their account, or that extra feeds will be charged.
  • Make sure your name appears followed by a bunch of abbreviations. I've always paid special attention to emails from my partner in Nigeria, Dr. Clement Okon, MD, PhD, DVM, MBA, ESQ, BS. Your customers will, too! 

That's it! I hope the techniques I've outlined above will help YOU become a more effective spammer.

Thursday, November 17, 2011

Twilight - Breaking Wind


Saturday, October 29, 2011

Gaia: Soccer Mom?!






































Is mother Earth, a.k.a. Gaia, a soccer mom, taking her "children" to practice in a planet-sized SUV?? Original story here.




Saturday, October 22, 2011

You and Your Dog


Saturday, October 15, 2011

Cannot Modify the Needed File

Upon restarting Windows, my StumbleUpon toolbar in Firefox seemed no more.

I went to the StumbleUpon site and tried to reinstall the add-on, but got this error:

StumbleUpon could not be installed because Firefox cannot modify the needed file.

My setup is a bit unusual in that I have a QSoft RAMDisk drive set up on my 4 GB system to utilize the extra 768 MB or so of PAE memory, normally inaccessible to Windows 7. I configured my system to use a folder on this drive, R:, named TEMP as a scratch space, and set up Firefox to use R:\ for its cache.



I discovered, however, that I'd forgotten to create a little script or batch file to create this TEMP folder on the R: drive. This meant that for some programs that might use the system's default temp space, it might fail, the folder R:\TEMP being nonexistent.

To get around this I simply modified my environment variables for TEMP and TMP to reference the root of the RAM drive, R:\. Now the StumbleUpon toolbar add-on installs successfully.

In case you encounter this error, make sure that you have sufficient space available in whatever folder you tell Windows to use as scratch space, and of course that it exists in the first place and is accessible.





Thursday, October 6, 2011

Sunday, September 25, 2011

Center Text AND Images Within ASP .NET

I recently integrated the handy AddThis sharing and analytics tool into an ASP .NET site I'm working on.

Whether due to peculiarities of the markup or browser idiosyncrasies, I couldn't get the widget consistently centered. The widget code lives in a div tag, and despite a popular few suggestions, I simply couldn't get things centered horizontally.

Centering text is no big deal; simply applying a CSS style usually does this well enough:

text-align: center;


Images, however, aren't accounted for by this markup. 

I ended up enclosing the widget in a Table control with the HorizontalAlign attribute specified to "Center", and this did the trick.


Centered!

Much easier to allow ASP .NET to handle the grunt work of emitting the necessary markup in this case than messing (directly) with styles.


Wednesday, September 14, 2011

Assembly must be Strong Signed in order to be marked as a Prerequisite

In the process of trying to update and rebuild a C# project utilizing Microsoft's Enterprise Library, I inexplicably got the error "Microsoft.Practices.EnterpriseLibrary.Data.dll must be strong signed in order to be marked as a prerequisite." 

I hadn't touched this project in a while, in fact I may've last built it on a different PC, so I guess if I had strong signed the Enterprise Library dll, the new system had no idea. Also, I'd installed .NET 4 recently, so maybe this had something to do with this earlier version of the Enterprise LIbrary (my project implements 4.1 whereas the latest version is 5). I guess security in the .NET 3.5 framework isn't up to snuff as far as .NET 4 is concerned.

Anyway, it appeared I had no choice but to use the sn.exe utility and create a key pair and do all the stuff Microsoft suggests in their painfully tedious article on how to sign an assembly with a strong name. Luckily after some digging I found Signer, a command-line utility which simplifies the process of strongly signing one or more assemblies which VS 2008 may be complaining about.

I'm referencing this from the perspective of a Windows 7 64-bit system, so note that the following may vary if you're using 32-bit. 

In order to do it's thing, Signer requires access to some other command line utilities, most of which live in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\. A few, however, including ilasm.exe and fusion.dll, live elsewhere (in my case, these were hanging out in C:\Windows\Microsoft.NET\Framework64\v4.0.30319).

I decided to copy Signer.EXE to the above SDK path, and copy the latest versions of the above files to that same path, so that when I execute Signer.EXE, it'll be able to easily find all the external EXE and DLL files in the same directory.

First of all, though, I needed to use MIcrosoft's sn utility to create an .snk key file in my SDK folder from a command prompt as follows:
sn.exe -k 1024 myProjectKeyName.snk

This instructs sn to produce a key file named myProjectKeyName.snk which I really don't care about for anything other than getting my project to build again. Thus, I chose an arbitrary key file name and value of 1024-bit key length.

I then executed Signer as follows in the same folder:
signer.exe -k myProjectKeyName.snk -outdir C:\myProject\myProjectLibrary -a C:\myProject\myProjectLibrary\*.dll

Here I'm instructing Signer to take the key I just created and strongly sign all .DLL files in my project's library folder. After this, I did a Clean Build on my project, then a Build, and thank goodness, the build completed successfully!
 
Even though Visual Studio 2008 can't build .NET 4 applications, I guess nevertheless since I have the .NET 4 framework installed, it's mandated that all assemblies shall be strong signed, or the project using them shall not build. Whatever, I'm just happy to have gotten past this issue.