Code by Kevin, Programming, code, business, and other pursuits
Kevin Walzer, software developer.
Subscribe to RSS Feed
Get a syndicated feed of my weblog.
Site design: Skeleton
As with all my apps, this version is a free update for registered users.Sun, 15 Jan 2017
I'm working on a round of application updates that are focused on (yet another) re-work of their application update mechanism.
This change has been driven by three factors: the recent upgrade of my websites to support encryption via Let's Encrypt; changes in Apple's API's in macOS Sierra to require encryption in web connections, and in how app updates can be installed on the system through a mechanism called App Translocation; and a desire to simplify the code of my app updates mechanism.
Let me address each of these in turn.
Encryption: This one is pretty easy. It just requires the addition of a Tcl library, TLS, to support encrypted web traffic. In addition to including the library, it requires a few lines of Tcl code, and then everything Just Works.
Apple's API's. The encryption part is simple, as discussed above. The "app translocation" API has taken me a bit more time to figure out and test; the only file format that Apple will allow to avoid app translocation (in the name of system security) is a signed disk image, or DMG. Zip files, tar files, and other formats don't get that benefit. (In app translocation, an affect application is copied to a hidden read-only format and then launched, to avoid injection of malicious code in the process; it also means the app cannot be updated or otherwise modified while it is running, which makes updates that Mac users expect impossible.) Using signed disk images instead of zip or tar formats is simple enough, and I've gotten it working after some trial and error.
Dissatisfaction with my code. For years I've tried to emulate the popular Sparkle app update mechanism in my apps. First I tried a basic imitation; then I tried to actually integrate Sparkle into my work; then I tried to use many of Sparkle's mechanisms under the hood and layer my own implementation on top of it; and, now, I'm back to doing a basic imitation. The reason for this is that I've never been able to cleanly integrate Sparkle itself into my work; it integrates perfectly with applications written in Objective-C, but I've never been able to figure out how to call it directly from Tcl, even if there is a C layer between. Later I used Sparkle's XML "appcast" mechanism under the hood, but this added a lot of complexity; Tcl's XML-parsing libraries don't play well with other scripting languages, which meant that I had to write additional code to parse the appcast if the application was written in, say, Perl. Additionally, my Tk-based knockoff of Sparkle's UI was just plain ugly.
So I'm back to a basic Tcl implementation that more or less follows Sparkle's example, using the following steps:
This format works pretty identically to Sparkle, at least in its basic moves; it's much simpler to maintain; and it will be portable to another platform, specifically Windows, whereas Sparkle is Mac only. Some Windows-specific code will be necessary to accommodate the differences in Mac and Windows installers, but apart from that, it will be identical.
I'll begin rolling this new update mechanism out in my apps in the near future.Sun, 04 Sep 2016
I'm pleased to release version 3.0 of TextSweep, my search-and-replace tool for OS X and, now, Windows.
This application represents a milestone for me: it's the last of my current applications to be withdrawn from the Mac App Store and the last that I will be porting to Windows. Some of my apps don't make sense on Windows (PortAuthority is a Mac-specific GUI for installing software, and Manpower's purpose--displaying man pages--is incompatible with Windows, which does not use man pages), but all that do are now available in Windows versions.
Going forward, I have some ideas for new apps, and these will be developed to target both Mac and Windows from the start. Additionally, new versions of my current apps will add new features and will also add Windows-specific features, when appropriate, to improve their performance and integration with Windows.Sat, 02 Jul 2016
Both releases are incremental updates, with slightly better performance and minor bug fixes.
Perhaps the most interesting aspect of these releases is that the source code for each is now posted online, at http://fossil.codebykevin.com, under the MIT license. While these are still commercial programs, the source code may be of use to users who would like to modify the applications for their own systems, or deploy them on a system that is not currently supported. While working with the source code is not something I will support directly, this may still prove of use to some folks, and I'm glad to offer it.Mon, 02 May 2016
I've released version 2.7 of FileMorph, my file modification tool for Mac and Windows.
This release fixes a serious crash on some Windows systems, and also incorporates some minor UI enhancements. If you are in the market for a cost-effective tool for changing file attributes such as their name, modfication date, and more, give this a try. As always, lifetime upgrades are free to registered users.Thu, 07 Apr 2016
In releasing the Python-based QuickWho 6.0 today, for the Windows version I followed the model I used for my Perl-based FileMorph app--I coded a stub executable in C that linked to the Python interpreter and made no effort to wrap everything up in a single "app" executable.
Python has more options for "freezing" or deploying standalone apps than Perl does, but the present state is a bit rough: none of the major libraries for Windows work to my satisfaction. Either they do not support Python 3.5, which has some significant changes over previous versions of Python on Windows, or they lack polish in certain respects in terms of customizing the icon or the version info bundled with the executable. This approach results in a larger distribution than the other approaches, but that's a trade-off I'm willing to make.
The other nice thing about using a C-based executable is that it can be ported to other languages with only minor changes, since all the languages that I use for desktop applications are themselves developed in C, and have a C API. The core of my exe stub does not change; it calls into Windows functions to set the working directory of the program, and requires only minor changes to hook into whatever language I am developing in at that time. This will make future projects on Windows simpler. (For an example, see http://fossil.codebykevin.com/fossil.cgi/quickwho/artifact/f3f87b14df46973c.)
The other thing I am doing with my Windows applications is using a simple installer and uninstaller setup that that includes only minor variations with each application. I use iexpress, a system tool that Microsoft includes with Windows to streamline the installation of software components and libraries. It essentially creates self-extracting archives, that only require a single click before each component is installed where I want. My installer package includes an installer script, an uninstaller script, a zip file of the application package, and a small unzip tool to decompress the archive. There are more complex software installer programs out there, both commercial and open-source, but iexpress is very simple and appeals to my Unix-based background. Developing the installer and uninstaller scripts was a great experience because I learned a great deal about Windows internals, its basic scripting language (batch), and so on.
I've released version 6.0 of QuickWho, my whois client for OS X and, now, Windows. This version features a major under-the-hood rewrite for increased accuracy, and various UI enhancements. If you would like a richer alternative to the command-line whois tool, it's a great product.
I've been away from work here since late last fall, working on other projects, especially my mobile apps. . I anticipate spending more time on desktop projects in the coming months.Fri, 13 Nov 2015
I've released version 2.6 of FileMorph, my file modification app for Mac and Windows. This version focuses mainly on Windows, with a substantially re-worked deployment structure that ensures smooth launching.
Apps written in Perl, FileMorph's main development language, are not easy to deploy on Windows. I prefer to use open-source tools rather than commercial toolkits like PerlApp from ActiveState, so I had deployed the last version using Par/PP, which creates standalone Perl application with all libraries bundled in a single executable file. Based on my research and testing, PAR/pp works fine for simple Perl/Windows applications that don't require a lot of polish.
However, for larger, more complex applications with multiple dependencies and professional-level polish--such as a custom icon, and standard application data such as version information contained in the executable--PAR/pp is seriously broken on Windows. Adding a custom icon and standard application text data is a non-trivial process, requires tools to actually hack the executable, and runs the serious risk of corrupting the executable to the point where it will not run. In my case, I got the executable to run, but at the cost of an extremely long startup time (over a minute) with a blank console popping up while everything loaded. After the application started, it still had issues: the default PAR icon still leaked out in places such as the Windows taskbar. While the app was entirely functional, it seemed rough, unpolished, and unprofessional.
This was unacceptable. I had held off on doing much marketing and promotion of FileMorph on Windows because it offered such a poor user experience out of the box. Something had to change.
After doing some additional research, I found a different approach that offered great promise: a simple stub executable that linked into Perl via its embedding API and did nothing but start the application. (The approach is outlined here: http://perl-node-interface.blogspot.com/2011/03/deploy-perl-application-on-windows.html.) I took interest in this approach because I've used something like it in my experimental ruby2app deployment tool for Ruby apps on OS X. I took the basic sample code for the Perl project, modified it to fit my application structure, and after some trial and error, got things working well. FileMorph now starts right up and, while the Windows download installer is much larger than before (60 megabytes vs. 20 megabytes), that's an acceptable trade-off for an application that runs well out of the box.
I commend this approach to any developer who is working with Perl on Windows; I am very pleased with it. While FileMorph is a commercial application, its source code is available under an open-source license at http://fossil.codebykevin.com/fossil.cgi/filemorph/timeline, so feel free to take a look. (As an aside, I also use a terrific module for deploying the application on the Mac: Mac::QuickBundle.)
And, of course, if you are an end user looking for a handy file modification tool for Windows, FileMorph may just do the trick--feel free to download and play with it. A one-time cost for a license includes free upgrades for life. It's worth your attention.Sun, 11 Oct 2015
After nearly four months since my last blog entry I'm pleased to announce the release of FileMorph 2.4.0. In terms of new features, this version is a minor update except for one thing--it now runs on Windows.
This isn't my first foray into Windows. When I tried it before, I went with an application that doesn't sell much, and I also spent longer porting it to Windows than I did trying to market and sell it--in short, I gave up pretty quickly. In this second go-round, I am planning on sticking with Windows for the long haul, because I need a second large market apart from the Mac outside the Mac App Store.
Of course, developing for Windows is not a simple process, and I had to re-learn several things about the platform; most of the last four months has been spent learning the particulars of Windows, and of re-working my development stack to support Windows. This means adding a lot of Windows details not just to a single app but to the entire suite of libraries I use to provide functionality to my applications: installation, user data, platform integration, and more. That work, at least, will be reduced with the next app I target for Windows.
I won't bore you with the technical differences between Windows and Mac--they are considerable, but not insurmountable. It is an interesting challenge to develop for a different platform, and I hope to learn more about marketing for that platform as well.Sun, 16 Aug 2015
These releases are the result of a two-month change toward looser enforcement of user registration, i.e. paying for a license to keep using the application after a thirty-day demo. I decided to make the releases nagware (they would pop up an alert if no serial number were found) but not otherwise limit their functionality, even after the 30-day demo period ended. The result was striking: without the requirement to pay, no one paid. I've had no sales over the past couple of months even with the usual number of downloads. Reviewing the rather large drop in sales revenue, I recalled this change I made to my registration code and concluded that was likely the cause. As a result, I've re-enabled the stricter registration code, and demos will once again expire after 30 days. Users who have been using the apps for the past couple of months without registering will eventually have to pay for a license if they want to keep using the apps. (You only pay once, by the way! Upgrades are provided free for life.)
Registration code is one of the duller parts of an application--a lot of housekeeping code, and surprisingly complicated, even with a fairly basic registration scheme such as the one I use. In the past my code has been prone to unexpected bugs that caused the code to freeze my application. There are a lot of scenarios a developer has to test for--the existence of a license or not, measuring how long a demo has run, and so on. It's not fun. To be honest, I eliminated the demo period because I wanted to remove the headaches of keeping the code tested and consistent. However, that code provides an essential function--ensuring that customers who continue to use my application actually pay for the work I've done. In fact, it's the most important function my code provides, from a financial perspective, especially now that I'm moving my applications out of the Mac App Store.
It's a bit disappointing that I have to use a stricter registration scheme to ensure that my work provides a bit of revenue, but I guess it's human nature to avoid paying for something if you don't have to. My code doesn't take elaborate measures to enforce registration, but it's strict enough to keep honest users honest, and that allows my apps to provide a bit of financial support for my business and family.