Thursday, December 19, 2019

Project Explorer: Automatically Digitally Signing an EXE After Building

When a customer reports a bug, we usually fix it immediately and send them a “hot fix”, which is usually just an updated EXE. Because it doesn’t go through our usual build process, the EXE isn’t digitally signed, which can cause issues on some machines. I created a batch file to sign the EXE but most of the time forget to run it before sending the EXE to the customer. Then it occurred to me I could automate that process using Project Explorer.

I created the following program and added it to the Addins subdirectory of the folder where Project Explorer exists:

lparameters toParameter1, ;
    tuParameter2, ;
local laStack[1], ;
    lnRows, ;
    lnI, ;
    lcApp, ;
     lcDescription, ;
    lcCommand, ;
    lcFolder, ;

* If this is a registration call, tell the addin manager which method we're
* an addin for.

if pcount() = 1
    toParameter1.Method = 'AfterBuildProject'
    toParameter1.Active = .T.
    toParameter1.Name   = 'Sign EXE after building'

* This is an addin call, so if we built an EXE, sign it.

if tuParameter2 = 3
    lnRows = astackinfo(laStack)
    for lnI = 1 to lnRows
        if 'projectexplorerui.vct' $ laStack[lnI, 2]
            lcApp = fullpath('..\', laStack[lnI, 2])
        endif 'projectexplorerui.vct' $ laStack[lnI, 2]
    next lnI
    lcDescription = inputbox('Description', 'Description for EXE')
    text to lcCommand textmerge noshow pretext 1 + 2
    "SignToolPath\signtool.exe" sign /fd SHA256 /tr /td SHA256 /f CertificatePath /d "<<lcDescription>>" /p Password "<<tuParameter3>>"
    lcFolder = justpath(tuParameter3)
    loAppRun = newobject('APIAppRun', 'APIAppRun.PRG', lcApp, lcCommand, ;
        lcFolder, 'HID')
endif tuParameter2 = 3
return .T.

Substitute SignToolPath with the path to SignTool.exe, CertificatePath with the path and name of the certificate file, and Password with the password.

This program is a Project Explorer addin that’s called after a project is built successfully. This code checks whether it was an EXE (we’re not going to sign an APP) and if so, finds the location of Project Explorer so it can use the built-in APIAppRun class to call SignTool.exe to digitally sign the EXE.

Now, whenever I build an EXE in Project Explorer, it’s automatically signed so I don’t have to remember to do it.

Monday, November 04, 2019

Southwest Fox 2019

If you missed Southwest Fox 2019, you missed a seriously great time. Check out the hundreds of photos (Facebook and Google Photos) our Social Media Manager Jody Meyer took and watch the Keynote presentation by Kevin Ragsdale on YouTube: Part 1, Part 2, and Part 3.

Congratulations to the 2019 VFPX Administrators Award winner Christof Wollenhaupt for his FoxMock project. Congratulations to the 2018 Speaker Award winner Tuvia Vinitsky.

We announced dates for next year's conference already, and it’s a little later than our usual October dates: November 12 - 15, 2020. I hope to see you in Phoenix next year!

Saturday, October 26, 2019

INTL is now open source!

Steven Black’s INTL Toolkit has been the tool of choice for years for developers needing to create international and multilingual applications. At the Southwest Fox 2019 keynote presentation, Cathy Pountney announced on behalf of Steve that he’d generously made INTL an open source project. Thanks, Steve, for this great contribution (as well as your many others) to our community!

Friday, October 25, 2019

Southwest Fox 2019 Keynote Presentation

Due to technical difficulties, the Facebook live video of the Keynote Presentation of Southwest Fox 2019 is unavailable, so we've posted it on YouTube: Part 1, Part 2, and Part 3.

Tuesday, October 08, 2019

Watch the Southwest Fox Keynote Live

We are using Facebook live video to stream the Keynote Presentation starting at 7:00 pm MST, Thursday, October 24. Kevin Ragsdale is presenting the keynote session titled “The Fox Family: A Whimsical Celebration of FoxPro and the FoxPro Community”.

Tuesday, August 27, 2019

Southwest Fox 2019: Early-bird deadline approaches

Because we were all busy this summer, we extended the Early-Bird Registration deadline, but it’s almost here. Save $50 by registering before this Friday, August 30th. Every registered attendee gets admission and white papers to all regular conference sessions plus free admission to the X# post conference session. Don't miss this chance to learn from the best and mix with your peers.

See you in October!

Tuesday, June 25, 2019

The FoxShow 86

Listen to Tamar Granor discuss women in tech, different ways of sharing information, and how to go from wallflower to presenter on The FoxShow 86.

Monday, June 24, 2019

Southwest Fox 2019 Super-Saver Deadline Approaches

Registration for Southwest Fox 2019 has been open for a few weeks and there’s less than a week until the Super-Saver Registration deadline. If you register before the end of June, you save $125 and we’ll throw in a pre-conference session worth $99. Not only that, but you’ll be entered in the drawings for a scholarship that will reduce your cost even more and a license of Stonefield Query SDK, a $2,500 value. Check out the speakers and topics on the conference website.

Please beat the rush so we still have some fingernails left when July begins! No need to wait, we won’t charge your card or cash your check until the middle of July!

Wednesday, June 19, 2019

The FoxShow 85

Join us on The FoxShow 85 for a discussion with Rick Schummer, one of the organizers of Southwest Fox, as we learn where he started, what and how he's learned to get to where he is, and why conferences will make him say "wow - how can I use that?"

The FoxShow 84

On The FoxShow 84, Andrew MacNeill and I talk about my start in the computer industry from Commodore PET and how much FoxPro development I do today. I'm also excited about the Southwest Fox conference and what I've learned from past conferences, and the real reasons people should attend (hint, it's not just the sessions).

Thursday, June 06, 2019

Integrating Project Explorer with Search Utilities

I’ve been using Project Explorer as a replacement for the VFP Project Manager for a couple of years now. However, I recently ran into a gotcha that I need to handle better. Here’s the story.

If you have it configured to do so (and I do), Project Explorer automatically generates the text equivalent of a binary file such as a form or class using whatever conversion tool you’ve specified (I use FoxBin2Prg) when you’re finished editing the item. I rely on this heavily: every day, I’m modifying some class or another, knowing the VC2 file is automatically created so I don’t have to do it manually. Since our source control repository contains only the text equivalents, not the binary files, this is very important.

The build process for Stonefield Query Enterprise Studio, the developer tool for the web version of Stonefield Query, runs on a build server. It pulls from the remote repository, uses FoxBin2PRG to generate binary files from the text equivalents, builds an from the PJX file, and uses Inno Setup to generate a setup executable.

Recently, one of our developers discovered a bug in Studio. It sounded like something I had just fixed, so I couldn’t reproduce it in my copy, but could in the version generated from the build server. I checked the VCX/VCT files from the build server and sure enough, the class had the unfixed bug. I checked my copy: it had the bug fix. Then I looked at the VC2 file on my machine and saw that the bug was still there. But how could that be?

Then I remember how I’d fixed the bug. I opened my project search utility (yes, I’m aware of GoFish and even use it from time to time, but my utility does 99% of what I need and is way faster), searched for some text, double-clicked the class it found, fixed the bug, and closed the Class Designer. The problem is that since even though Project Explorer was open, it wasn’t asked to open the class, so it didn’t know the class had been changed and didn’t call FoxBin2PRG to generate the VC2 file, so the bug still existed in that file and in our repository.

Of course, it was easy to resolve the problem: generate the VC2 file for the class, commit the change, push to the repository, and run the build process again. But I wanted to make sure this didn’t happen again, so I added a new method to Project Explorer: EditFile. It has the same syntax as EDITSOURCE, but when you close the editor, Project Explorer automatically calls FoxBin2PRG if the file is a binary just like it does if you click the Edit button in Project Explorer. Then I edited my project search utility:

if type('_screen.oProjectExplorers') = 'O' and _screen.oProjectExplorers.Count > 0
    loPE = _screen.oProjectExplorers[1]
endif type('_screen.oProjectExplorers') = 'O' ...
do case
* Other code here.
    case FILES.TYPE = FILETYPE_FORM and vartype(loPE) = 'O'
        loPE.EditFile(lcFileName, lnLineNo, justfname(lcFileName), lcMethod)
        editsource(lcFileName, lnLineNo, justfname(lcFileName), lcMethod)
    case vartype(loPE) = 'O'
        loPE.EditFile(lcFileName, lnLineNo, lcClass, lcMethod)
        editsource(lcFileName, lnLineNo, lcClass, lcMethod)

So, when I tell my utility to edit a file containing the search text, it either uses EDITSOURCE if Project Explorer isn’t open or it calls Project Explorer’s EditFile method if it is. Problem solved. The latest version of Project Explorer on GitHub has this change.

I haven’t updated GoFish or Code References but posted an issue with both projects in case the developers or someone want to add support for Project Explorer.

Wednesday, May 22, 2019

Southwest Fox 2019 Registration Now Open

Registration for Southwest Fox ( is now available. See for a list of speakers and for a list of sessions. Super-Saver Registration, which saves you $125, is available only through June 30th, so don't wait.

Putting on a conference is a risky endeavor. Conference centers require a guaranteed minimum income to block the dates of a conference; for a conference like Southwest Fox, that minimum is in the tens of thousands of dollars. We have to commit to the conference center by July 2nd and need your support by July 1st to make that commitment. We will not send out any "We need your help" appeals so please do not wait; register by June 30th! We know most of you like to wait until the last minute to avoid the credit card bill arriving too soon. We will not charge any attendee credit cards or cash any checks until we have committed to going forward (sometime after July 2), so this is not is a reason to wait.

Rick, Tamar, and I look forward to seeing you in October!

Monday, May 06, 2019

Southwest Fox 2019 Speakers and Sessions Announced

Speakers and sessions for Southwest Fox 2019 have been announced. We like to have at least one new speaker each year, and this year it’s Tracy Pearson, presenting sessions on calling VFP COM objects in C# applications and implementing automated builds for VFP applications.

Besides Tracy’s sessions, I’m especially looking forward to seeing the following sessions:

I am, of course, also fired up about doing my own sessions: Creating Dynamic Object-Oriented Reports and Menus and Adding Features to Your VFP Applications Using C#. I think the latter is going to be really useful for anyone wanting to add new features to their VFP applications that would be difficult to do in pure VFP code but relatively easy using .NET.

Monday, March 18, 2019

Minimizing West Wind HTML Help Builder Uploads

I’ve been using West Wind HTML Help Builder for about twenty years (it’s hard to believe it’s been that long, but I checked) and still love it as much as ever. I looked at a lot of HTML Help generating tools over the years and it’s still the best one in my opinion.

One of the features I love about it is the ability to generate not just a CHM file for a desktop application but also HTML files for a web application or to post the documentation on a web site. For example, we provide online versions of the developer and end-user documentation for our products (for example, for the Stonefield Query report designer), both so prospective customers can review it before they buy and so we can point customers asking support questions to the relevant topic with a simple URL instead of “open the help, then navigate to …”.

At a recent conference, I was asked if there’s a way to reduce the number of files needed to be deployed to a web site to provide online help. I used to deploy the files directly from the project folder so I wrote some code that uploaded only those files that are actually required because there are a ton of files that aren’t. Fortunately, I don’t need to do that anymore because a new feature in Help Builder does this automatically: after building the help, click the Copy to Folder button to create a deployment folder with only the required files, then use something like FileZilla to upload the contents of that folder to the web site. FileZilla and other FTP programs are typically faster than homegrown code like mine or the code used for the FTP Web Upload function in Help Builder, likely because they use multithreading to upload several files or chunks of files at once rather than one at a time.

However, even the Copy to Folder function copies a few more files than necessary. Here are files you can delete from the deployment folder before uploading (which of course you could automate with a PRG or PowerShell script):

  • bmp: any images for topic types you aren’t using, such as classcontructor.png. Typically, the only ones I keep are folder.png, header.png, index.png, topic.png, and whatsnew.png. Also, the contents of the image subdirectory of the bmp folder aren’t used anywhere and can be deleted.
  • html: this folder is empty and can be ignored.
  • images\images: the only file in this folder is wwhelp.png and it doesn’t appear to be used anywhere (there’s another copy of this file in images, which is used in the various HTML documents unless you customize the templates to not use it as I have).
  • templates\scripts: ww.jquery.js: this is the unminified version of ww.jquery.min.js.
  • templates\scripts\bootstrap\dist\css: bootstrap.css,, bootstrap-theme.css, these are unminified versions of other files or map files which aren’t needed.
  • templates\scripts\bootstrap\dist\js: bootstrap.js, npm.js: unminified or unneeded files.
  • templates\scripts\highlightjs\styles: any css file you aren’t using, as determined by the Theme setting in the Content Editor page of the Options dialog. I typically use vs2015.css in my projects so I delete the rest.
  • templates\scripts\jquery: jquery.js, unminified or map files.

Removing unused files saves about 1.5 MB, which may not sound like much in these days of large hard drives, but that shaves a bit of time off the upload process.

Wednesday, March 13, 2019

New FoxMock Project on VFPX

Christof Wollenhaupt’s FoxMock project is now available on VFPX. FoxMock is an object mocking framework that works with testing tools such as FoxUnit to make it easy to define objects without having to create specific test classes. Christof discussed FoxMock in one of his sessions at Southwest Fox 2012.

Tuesday, February 19, 2019

Southwest Fox 2019 Call for Speakers

We've issued the Call for Speakers for Southwest Fox 2019. If you are interested in presenting, please read the document referenced in that page and consider submitting sessions via the Geek Gatherings Submission Web site.

Thursday, January 24, 2019

Update to VFPX Upsizing Wizard

I released an update to the VFPX Upsizing Wizard today. It has a couple of changes:

  • It handles large tables better. The bulk XML load process, which is by far the fastest way to upsize the records in a table, creates an XML file using CURSORTOXML and then uses the SQLXML COM object to process that file. With a large table, the XML file could be more than 2 GB, which causes CURSORTOXML to fail, so the Upsizing Wizard reverts to using a slower mechanism. In this update, the bulk XML load routine now processes large tables in batches so the XML file never gets bigger than about 1 GB.
  • It renames the built-in tables Keywords.dbf, ExprMap.dbf, and TypeMap.dbf to have an underscore prefix to avoid conflict with tables using those names in the database to be upsized (this was an issue someone ran into).

Note: since SQL Server 2008, the SQLXML module that supports bulk XML load is no longer automatically installed, so if you find bulk XML load isn’t being used, it may be because the COM object doesn’t exist. In that case, download it from