16 years with Flash Renamer – A development retrospective

Of all the applications, web services and games I have made or been part of, Flash Renamer is my darling. In case you don’t know, Flash Renamer is a Windows utility for batch renaming files and folders. It’s my own creation and reflects much of my own needs and way of working, while still trying to suit a broad user base. I started working on it a whopping 16 years ago, a respectable age for any software. Like all software published on my website, it is purely a hobby project that I developed in my spare time. I wanted to write a little bit about the story of how Flash Renamer came into being and developed through its versions, as well as some more general reflections on software development.

Flash Renamer 6.73

The current version of Flash Renamer.

The start of it all

It was early 1998 and I had discovered mp3:s. I was fascinated by this new way of storing “CD quality” music and had started to download music to build up a little collection of music that I liked (mostly euro dance :-)). I was however quite picky with the file names, and put a lot of thought into how to best name the files. They should convey as much information as possible, yet still look good and be easy to read. Bare in mind that this was before the ID3 metadata tag had become mainstream, or even supported by applications.

I quickly discovered that naming the files by hand was quite tedious though. So, I did a web search to try and find a solution. But I could only find one batch rename program (“THE Rename“). Unfortunately it did not start on my computer for some reason.

I knew a little programming, but I didn’t use any particular programming language at that time. But I had gotten Visual Basic 4 on a magazine cover disc and I liked how easy it was to make graphical Windows programs with it. I had cobbled up some simple applications with it before, and, for some reason I can’t remember, decided to make a batch rename application for myself.

The origins of Flash Renamer hints at one of the great things about knowing how to program a computer: if something does not exist that you need, you can make it yourself!

Origin of the name and interface

Finding a good name for a new product is hard, so I usually just give my new projects a name based on its purpose until I can figure out something better. In this case I simply named the new program Batch Renamer. Included in Visual Studio was a set of stock icons. For some reason I though the lightning bolt icon looked cool and used it for the program. The name Flash Renamer is simply derived from this randomly chosen icon! (This was before Macromedia/Adobe Flash become popular and pretty much hijacked Flash as a brand name. Luckily I have not had any visits from Adobe lawyers!)

Flash Renamer has a distinctive user interface layout that makes is stand out from most other batch renamers I’ve seen. I’ve always been satisfied with it, and based on user feedback it appears to be appreciated. What’s interesting is that this layout actually dates back to this very first version. Of course, it has been heavily updated and tweaked throughout the years, but the basic design clearly stems from the very beginning. Pure luck or a stroke of genius… who knows 🙂

Flash Renamer Beta

One of the earliest surviving version of Flash Renamer. The layout is a mess, but the basic ideas are there.

First public version

In March of 1999 I made Flash Renamer 1.0 available as freeware on my personal homepage.

Flash Renamer 1.0

Flash Renamer 1.0. Now all the pieces had fallen into place. It’s a little base, but you can easily see the heritage when compared to the current version.

During the next couple of months I updated the program several times to make it look and handle better, and of course ironing out bugs. It’s hard to remember, but I probably submitted it to a few software sites during this time, such as TuCows and NoNags. I remember getting 5 stars out of 6 at NoNags. (Later on, version 3 got 6 stars!).

Flash Renamer 1.3

Flash Renamer 1.3 improved the look and feel.

The first versions could rename both files and folders, including subfolders, and came with three rename functions: Find and Replace, Convert Case and Set Attributes. These pretty much represents what I needed to do with my mp3:s, namely replace underscores with spaces, set the casing to title case and remove write protection 🙂

The early versions

1½ year after the first version I released Flash Renamer 2.0. I added support for reading ID3 tags in mp3 files using code I wrote myself. In retrospect it does not sound impressive, but I was fairly proud of myself at that time, especially considering the limited documentation and that Visual Basic is not exactly known for its ease of binary processing. This was a time when mp3 was rising in popularity, but before it had become a household name. Adding mp3 support was probably a very good decision from a strategic point of view, although I mostly added it because I wanted it myself 🙂

Flash Renamer 2.0

Flash Renamer 2.0. You could “design” your mp3 filenames using “tags” that were replaced with ID3 metadata during renaming. The concept of tags was later expanded and used throughout Flash Renamer.

Version two also included the Add & Crop function, a command line interface and a real user manual, to name a few.

Version 3.0 came out half a year later and was quite a big upgrade, adding several new rename functions, simple shell integration. Now the program also got its logo, courtesy of Ola Zandelin.

Flash Renamer Logo

The Flash Renamer logo

One cool feature was the file type detection, which scanned the files for magic numbers to try and figure out the correct file extension. This came about because people were uploading (usually not very legal) files to free web site hosts. In order to try and circumvent restrictions and risk of detection, they changed the file extensions from for example mp3 to a permitted file type such as gif.

Version 3.1 finally replaced the wording on the button that started the rename operation. Up until now it had said Execute, but I realized that this might not be that appropriate. I changed it to simply say Rename, which is also much more telling of the button’s action. Wording is hard. You want to convey the message in a way that is understandable to everyone without losing exactness. I think programmers tend to use too much technical terms, reducing the usability of the software. Other examples from Flash Renamer include Crop which became Remove, and Directory, which took me a lot of weighing back and forth before I finally decided to replace all occurrences of the word with Folder. And let’s not forget the function that can add a number sequence to filenames, which I first called Enum… Oh, and the Zero Padding functionality, which I first called Number Normalizing because it sounded cool, not realizing that it was actually a completely irrelevant mathematical term 🙂

Flash Renamer 3.0

Flash Renamer 3.0. The tab control is getting tight with all the new functions.

Going shareware

At this time, me and some friends had started a company together, called RL Vision, and tried to market a paint application called ArtGem, inspired by the classic Amiga application Deluxe Paint (DPaint). In order to drive more traffic to our homepage I decided to move Flash Renamer from my private homepage to our company website. ArtGem eventually failed, and the company was disbanded, but I kept the RL Vision name and website as my personal software outlet.

I was fairly pleased with Flash Renamer at this point. It was a competent and stable application. It satisfied my own needs and I had gotten some praise from users. I had some ideas on how to make it better, but felt my time was limited and I was not sure I wanted to invest more in the program. At this time there had emerged a few other file rename software. At least one of them was shareware. Even though ArtGem had sold poorly, perhaps Flash Renamer would do better? I decided to give it a try and turned Flash Renamer from freeware to shareware. This was quite easy, considering that we already had the infrastructure for selling software in place after selling ArtGem.

This decision gave me the motivation to update Flash Renamer. Version 4, the first shareware version, was a big update. I replaced the rather odd file listing that used a treeview with a listview similar to Windows Explorer. This also worked as a file browser, making it fast and easy to navigate your folder structures. I also added support for viewing images as thumbnails and for reading ID3v2 metadata tags, both using third party library. Together with many other smaller features and enhancements, this version turned Flash Renamer into an application with a much more professional look and feel.

Flash Renamer 4.0

Flash Renamer 4.0 was a big update that really improved the interface. The name/logo in the top left was not the pretties though…

In version 3 I had a “simulation mode” feature that allowed you to run the rename operation without actually renaming the files. Doing so, you could inspect the log output to make sure that the new filenames were ok. With the new listview I took this to the next level, adding a preview column where you would instantly see the new filenames next to the original! This was quite tricky, since Visual Basic does not support threading. Generating filename previews take time, and would cause the UI to freeze meanwhile. I solved this by running the preview on a timer, only processing a few files at a time. Neat!

Most shareware have some limitation or annoyance to make you register. My solution was to open a window on top of the main window at startup. This window displayed a counter, counting up to the total number of files you had renamed using the program. You could not continue until the counter had finished. Thus, the more you used the program, to longer it took to start. I thought this was quite a fair way to annoy people into register, without having to limit any other functionality. (Later versions removed this counter though.)

Flash Renamer Shareware Reminder

The shareware “nag window”

I am a terrible businessman. From the very beginning, I promised free lifetime upgrades when buying Flash Renamer. Part of this was of course as an incentive to buy the product. But just as much was the simple fact that this is how I would like other software to work as well. I understand that “lifetime” is difficult for most businesses. But some software vendors seem to have made it into a business model in itself to constantly get people to pay for upgrades, and I really hate that.

Buying Flash Renamer also gives you free technical support by email. But the truth is that I help anyone who emails me just as much, no matter if they are registered or not :-). But this is probably a good strategy, because often people ask questions on how to use a program for their situation, before they actually buy a product.

After the failure with ArtGem, I did not expect Flash Renamer to sell much. But to my surprise, without any marketing, it started to sell a copy every now and then. The earnings are not anywhere near enough to make a living out of, but it is very satisfying knowing that you made a product on your own that people are prepared to pay for.

Useful functionality or bloatware?

I continued working on Flash Renamer, adding new functionality and tweaking the program to perfection. Some, like reading Exif tags, were a result of user requests and/or market study. But most new development stem from my own experience of using the program. I am a firm believer that dogfooding is the way to success.

One new function was batch replace. Find and replace had been a function since the first version, but realized that you often have a set of terms that you always want to replace to clean up your filenames. So the batch replace function is basically a list of find/replace terms. Inception?

Flash Renamer 5.0

Flash Renamer 5.0. This screenshot also shows the “Visual Assist” utility, that helps the user to pick places and select texts. This is one of my favorite enhancements, as it is a good example of how you can make an application easier to use.

In version 5 I added a shell extension, hooking into Window Explorer to allow the user to right click on files and send them directly to be renamed by preset in Flash Renamer. It was a very convenient integration IMO. But the development was oh so problem ridden. Let me just say that I don’t recommend anyone to build a shell extension menu unless you really know your way around the Windows API. And I especially don’t recommend anyone doing it in VB6 🙂 It was so much trouble to build, debug and maintain. Then 64-bit Windows got its breakthrough, and 32-bit shell extensions because useless. At that point I decided to stop supporting it.

Flash Renamer Shell Extension

The Flash Renamer shell extension menu in Windows Explorer

Version 6 included ID3 tag writing functionality for mp3:s. This brings up the interesting topic of what you want your application to be? At its core, Flash Renamer modifies filenames. How far from this core can (or should) you stray without losing your identity and risk becoming bloatware? Flash Renamer has the ability to change file’s dates and attributes too. I would argue that this is fairly close to the core, as the filename, date and attributes are all properties of a file. But writing ID3 tags? That’s pretty far from the core. But you could argue that you are modifying the content inside the ID3 tags to suit your needs, which is pretty close to the idea of modifying filenames to suit your needs. But that’s a slippery slope, as using this argument we can easily motivate lots of other operations. For example, why not let Flash Renamer open and modify the content of text files too then? In fact, I had this idea, but decided to fork Flash Renamer into another product called Replace Genius. That was probably a wise choice. Back to the ID3 writer. The biggest motivation for this was the fact that much of user base (and I :-)) use Flash Renamer to manage mp3:s, and ID3 is an essential part of this. Thus I believe that writing ID3 tags is an added value to Flash Renamer.

Flash Renamer 6.0

Flash Renamer 6.0. Instead of adding a third row to the tab control, I sorted the functions into categories (the round buttons) that changed the tabs.

Scripting is another interesting feature. It allows anyone to make their own custom rename functionality to suite to their specific needs, through a simple VBScript interface. There is something really attractive about opening up your software to users and other developers. But is it worth the work? When choosing what functionality to implement in a piece of software you always have to weigh it against how useful it will be for the end users. If only a few people can be expected to find it useful, then it is hard to motivate implementing it. Scripting in a sense is a way to enable the program to implement such odd functionality without cluttering the interface too much with features that no one uses. But you can also argue that scripting in itself is such an odd functionality. Even though I believe that the user base of Flash Renamer in general is quite computer savvy, I don’t think that that many have the skills or motivation to actually construct their own scripts. Probably only a few people have ever used the scripting functionality. But I still like it for some reason 🙂 And it has also allowed me to implement some odd functionality that I thought was neat, but not neat enough to motivate a new function.

The future of Flash Renamer

At this point I am pretty much done with Flash Renamer. There are many things I can think of that would be cool to add to the program. But all essential features are there. Sometimes you have to say stop. Letting go of Flash Renamer means more time to other projects (and life).

Continuing developing a VB6 application today does not feel meaningful. It is tempting to re-write Flash Renamer in another language. Like all programmers I think that I could make it so much better in all kinds of ways. But the motivation is not there. Why re-do something that works and fulfills all my personal needs? Perhaps if there had been a “real” market for such an application, but there isn’t.

I will however continue to support the program for as long as it sells, and then some more. I hate software vendors who drop products and bail out of responsibility. I am working on open sourcing all my freeware products, and when the time comes I will also make sure that Flash Renamer is open sourced.

User feedback

One of the most grateful things with making software is the user feedback you get. Of course, much of this feedback is bug reports and feature requests, but I also get letter from people thanking me for my work. I’m always happy to hear from my users, and I make sure to answer all letters, even if only with a simple “thank you”. I remember one of the earliest mails I got when the first versions of Flash Renamer had just been released. This guy from Japan wrote to me to report a bug. Imagine that. Half way across the world someone completely unknown to me had found my personal website, downloaded my program and was using it. That felt pretty cool at the time, for many reasons.

Most new functionality in the later version of Flash Renamer has been a combination of user feedback and my own ideas and needs. Flash Renamer gets a lot of feature requests from user, which I guess is expected since all users have their own specific needs. While I appreciate the feedback, I can rarely implement such requests. I have to distill the feature into a more general functionality that can appeal a broader user base. It saddens me to usually write back thanking users for their suggestions, but having to tell them that I most likely will not be able to implement it.

Visual Basic is dead, long live Visual Basic

When I started programming Flash Renamer, Microsoft Visual Basic 6 was the coolest thing in town, at least if you could stand being ridiculed by “real” programmers who used C/C++. Not so anymore. Microsoft decided that .Net was the future, and simply stopped development of classic Visual Basic in order to get people to switch. Sure, there was VB.Net, but that was a completely new thing, basically only sharing some language syntax with its predecessor. Upgrading was not a simple task, if even impossible, and most people seemed to do like me and ignore the “VB7”.

Working with an obsolete technology has been difficult at times. The most obvious problem was the new “XP themes” introduces in Windows XP. Getting your program to fully use these was problematic, and required many tricks and hacks. I must however hand it to Microsoft that they are good at backwards compatibility. Even though Flash Renamer is built with ancient technology, it still works, even in Windows 10! Old software tends to “just work” in Windows. This is so much better IMO than companies like Apple and Google, who seems to have no problems throwing out “old” technology. Developers need to constantly keep up with changes or go out of business. It’s no wonder that Microsoft is the choice of large corporations, and not Apple.

Choosing a programming language

VB6 was my main programming language for a long time. But eventually I had to face the fact that I needed to find something else. It took me a long time before doing so though. Given how bad VB6 developers had been treated, I did not want to end up like that again. I wanted a high level language with a readable and productive syntax, sustainable in the long term with a large community, preferably cross platform, producing native applications and with a good IDE for easy GUI development. I finally settled on C#. It did not fulfill all my wishes, but it was the best I could find. I’m not sure I would have chosen differently today, but there sure are many more choices out there today, especially with all the new web based technology. In the end it is nearly impossible to choose the “best” language for the future. In the world of development, change is rapid. Even if you have a favorite programming language, developers more and more need to be open to new technologies in order to survive on the market.

The world of open source, available libraries and development communities has exploded compared to when I began working on Flash Renamer. Today you often put together new software or services by piecing together various components. You don’t have to write as much code yourself anymore. And if you do, the amount of documentation and help available online is astounding. If I had to redo Flash Renamer today, that would probably be the biggest change. Less code, more puzzling to make things work together.

On being a software developer

I hardly earn any money to speak of from my software. In the end, the number of hours spent on developing Flash Renamer far exceeds what I’ve earned. It’s very hard to earn a living on shareware unless you have a major hit. For me, development is a passion. I don’t do it to earn money, but because I really enjoy coding and sharing my work. So much that I spend my free time after work doing it. I think this is a quite common theme amongst developers. Just think of all the open source and freeware products available today and how much this has contributed to the computer landscape ever since it begun.

I am a reasonably good programmer today. I am not one of those with an innate talent for programming though; my talent is more based on experience. Developing applications at home has definitely helped me with that experience, and thus helped my professional career. On that note, when seeking a job, having something of your own to show is worth a lot!

Developing a product on your own requires more than just programming (although it usually starts out with just programming). You need to design graphical user interfaces and consider usability issues, think about software architecture, create web sites, writing copy and manuals, handle business tasks, give user support and so on. Such a wide range of tasks is something you would never get to do in a larger organization. It is much work, but can also be rewarding and develop you as a person.

The downside of being a one (wo)man team is of course that you can’t be an expert on everything, and there is no one there to give immediate feedback or help when you need it. You have to make all the design choices yourself, and that is very hard. Designing and tweaking the user interface, deciding on how to implement a feature, making architectural choices, taking into account all possible user needs and circumstances. These kinds of decisions are what tends to take the most time for me when developing something. Programming is actually pretty fast and easy if you know what exactly what you need to do.

Closing thought

Sometimes I wonder how many files “my little utility” has renamed. I’m sure it’s tens of millions, perhaps even billions? But more importantly, how many hours of manual labor has it saved people all over the world!? Thinking of it like that makes it clear even if it is just a fairly unknown program with a small user base, the amount of saved work is not *that* insignificant. It feels good knowing I made the world at least a little bit better 🙂

Flash Renamer About Window

My current copy of Flash Renamer has performed roughly 80,000 renames since I installed it about 3 years ago.

Posted in Articles | Tagged , , , , , , , , , , , , , , , , | 1 Comment

Using wildcard matching in any programming language

Most computer savvy persons are familiar with using wildcards when listing files and similar operations. Wildcards are quite easy to understand and use. An asterisk * means match anything, and the lesser known question mark ? matches a single character. So when creating our own applications we often want to give our users the ability to search with wildcards. The problem is that most programming languages don’t have a wildcard string matching functionality. But it is actually quite easy to implement on your own. All you need is to use Regular Expressions in a clever way.

Wildcards can be seen as a subset of RegEx; anything you can do with wildcard can also be done with RegEx. In RegEx the period (.) symbolizes any character. We can add an asterisk (star) after the period (.*). The * quantifier tells RegEx to search for zero or more of the preceding value, in this case any character. That sounds a lot like the asterisk in wildcards, doesn’t it? Similarly, the ? modifier means zero or one of the previous value.

So what we need to do is to convert our wildcard search into a RegEx search. This outlines the process:

  • First we need to escape the search string to convert any special character in RegEx into character literals.
  • Next, locate the wildcards and convert them into proper RegEx patterns.
  • You probably also want to set the RegEx match to be case insensitive.

This can be used in all programming languages that support Regular Expressions. Exact syntax and RegEx dialect may vary though. Here are two examples that I made, one for C# and one for JavaScript:

C#

JavaScript

When implementing this in your own code, you need to think through how you want your search functionality to work. Perhaps you want case sensitive search? How should the  beginning and end of strings be handled? Is the “greedy” property of RegEx desirable? Perhaps you need to add some more RegEx to control such behavior.

Resources:

Posted in Development | Tagged , , , , , , , | 1 Comment

Fixing the ‘PRM_ParserErrorDetails’ problem for SharePoint Apps

Today I finally solved a problem that I have been trying to hunt down for a long time. I haven’t been  able to find any good help on this elsewhere, so let me share how I solved it.

This is my setup: I have SharePoint Online site, where I open a modal window to load a page from a provider hosted app (Add-In). The app is running in Azure Websites (Web Apps). The page is built with ASP.Net WebForms and displays a simple form that you submit back to the app.

The problem was that when you clicked the submit button in Internet Explorer, a JavaScript in MicrosoftAjaxWebForms.debug.js crashed, preventing the postback:

PRM_ParserErrorDetails

Other browsers worked fine though. The solution was stupid simple, but easy to miss:

The Azure site need to be added as a trusted site in Internet Explorer!

Add to trusted sites in Internet Explorer

For the curious: The postback never seemed to make it back to the server. Actually it did, but it got stuck in the Page_PreInit() mehod, where SharePointContextProvider.CheckRedirectionStatus()  returned a “RedirectionStatus.CanNotRedirect” and the the connection ends.

Posted in Development | Tagged , , , , , , | Leave a comment

Moving web parts in SharePoint (without going insane)

If you’ve ever edited a SharePoint 2013 page with web parts and tried to drag them around, you’ve probably experienced frustration over how bad it works. I don’t know of a quick fix for this, but here are a few tips that might help you a little bit:

First of all make sure that you are using Internet Explorer 9 or 10. IE9 works best. Other browsers, including IE11(!), will not work in a satisfactory way.

Tip: In Internet Explorer, press F12 to open the developer tools. In the top right corner of this toolbar you should see a drop down menu for selecting “document mode”. Use this to revert back to previous version of Internet Explorer even if you have the latest version. (Note that “Edge” in this context refers to the latest rendering engine (typically IE11) and not the new web browser from Microsoft with the same name.)

Here’s my best trick to handle web parts that just don’t want to move: Suppose that you want to add space between two web parts (or above the topmost web part). It’s seems impossible to place the cursor in between the web parts. But you can place the cursor at the very bottom of the web part zone, below the last web part. Do this and hit enter a few times to make extra room at the bottom. Now grab on to the web part and drag it downwards until you see the cursor appear in the new space that you just created. Release the mouse and the web part will move down a few steps!

Other things that are good to know:

  • The ability to move web parts depends on the type of page and/or area it is located in. Web Part Zones usually work fine. You can even drag web parts between different zones. It is Wiki pages and rich text fields that cause trouble.
  • Try to drag a web part and simply drop it on top of the web part above. Usually this will reorder them.
  • If you mess up, Ctrl+Z usually works to undo the last steps.
  • Web parts can be minimized so only the title shows. This can be useful when working with web parts taller than the screen height.
  • For web parts located in a Web Part Zone, open the web part properties (the gray sidebar) and find the section named “layouts”. Here you can manually both set the zone and internal ordering of the web part.
  • When everything else fails, remove the web part and add it again. New web parts are consistently added to either the top or bottom of the web part zone. Use this fact to plan the order of the web parts.
Posted in Tips | Tagged , , | 3 Comments

What data recovery companies aren’t telling you

My freeware utility Snap2HTML has turned out to be popular among data recovery companies, who can use it to send customers files listings of potentially recoverable files.

Typically you send your damaged disk or other media to the recovery company, and they will assess the damage and get back to you with an estimate of the files that can be recovered. This evaluation is usually free, and you pay to actually have your files recovered and sent back to you.

But here’s the thing. If they can tell you what files can be recovered, then they have most likely already recovered your files! That’s right. The job has already been done. They are just waiting for you to pay up so they can send you your files.

I’m by no means an expert on data recovery, but I think it makes sense if you consider that trying to read a damaged disk may cause further damage. Thus you can’t afford to read it multiple times. So the data has already been read and stored on a another disk. Then they would need to identify the file tables and match with file data. Once that is done, I would imagine that the files are ready to extract. Only now would it be possible to tell which files are actually possible to recover and at what health.

Showing the customer what data “may be” recoverable gives a great bargaining opportunity for the data recovery firms. I have no intention of badmouthing them, they do a great job and provide a valuable service, but I believe that customers have a right to know what is going on behind the scenes.

Posted in Articles | Tagged , , , , | 2 Comments

Forcing JavaScript reload in Internet Explorer

If you develop websites in Internet Explorer you may experience trouble reloading your  updated JavaScript. I ran into this problem myself when developing SharePoint Online  apps using IE11. The JavaScript was located on an external Azure website and did not reload when I published new versions, not even if I hit Ctrl+F5 to try to force a complete reload. I figured out that you could get around the problem if you do like this: Open the F12 developer tools and go to the debugger. Here locate your JavaScript and open it. In the script, press F9 to set a breakpoint anywhere in the code. Now when you refresh the page Internet Explorer will always reload the script. Problem solved, provided you can stand an annoying breakpoint each reload 🙂

Posted in Development | Tagged , | Leave a comment

Setting “Allow Fill-In” on taxonomy fields with CSOM

SharePoint taxonomy term sets can be open, allowing users to enter new values in the taxonomy picker. For this to work you also need to enable Allow ‘Fill-in’ choices in the site column settings for the managed metadata field connected to the term set. It took me a while to figure out how to enable this programatically using the client side object model (CSOM). The trick is to first cast the field to a TaxonomyField so you can edit the taxonomy specific properties on the field:

Posted in Development | Tagged , , | Leave a comment

Working with the AppInstalled and AppUninstalling events in SharePoint Apps

Some quick notes about remote app events receivers I have picked up when working with apps in SharePoint Online.

When is AppInstalled triggered?

When you add an app in SharePoint Online it shows in Site Content as being added. Installing an app in itself is nothing special, so you might expect the AppInstalled event to trigger pretty much instantly, but not so. There appears to be some kind of queue system employed here. Usually the queue is short and the app installs quickly, but sometimes I have had to wait for several minutes before the installation started.

AppInstalled can be triggered several times

If your app needs to deploy a number of items to the host web it may take a while to complete the installation. Other times your installer could be slow because the server is under heavy load or you are debugging. Even if your app is still up and running and performing the installation and thus communicating with SharePoint, if it does not complete the installation within a certain timespan SharePoint will think that the installation failed and try again. SharePoint retries up to four times by design. How long is this timespan you ask? It varies. Usually I see retries in about 15-30 seconds in my logs. But it is unpredictable and sometimes it seems to retry in as short as a few seconds. As an example, here is an extract from a log session in one of my apps:

There does not seem to be a way to tell SharePoint that your installation will take time and ask it to be patient, so you need to handle these retries in some way. You should start by building a robust installer that can handle situations when elements are already installed. This is always a good thing, but not enought for the above stated problem, because there could be a race condition: how would you know if another thread has not just begun installing the element your thread wants to install?

Another way could be to let your server threads communicate with each other, as suggested by AkhileshN. If the first call is still running, subsequent calls could halt or return directly. I tried this and it works, but you run into another problem. The first call will either succeed or fail. The subsequent calls can not simply return success, since SharePoint will think that install succeeded even if the first call later returns failure. And how do you know that SharePoint is still listening to the first call? This can quickly become hard to manage. Myself I decided not to use this approach.

My solution was to only perform a few basic tasks in the AppInstalled event. I mostly put validation checks there to make sure that it is ok to install the app on the specific host web. Then the user will have to open up the app and complete the installation from there. Sometimes I do provision a few elements in the AppInstalled event though, since this will improve the user experience. Just make sure you know what you are doing and test thoroughly so you understand what is happening.

AppUninstalling event does not trigger?

If you’ve tried to listen to the AppUninstalling event in your SharePoint app but never gotten it to fire you’re probably not alone. The AppInstalled event is triggered when you add the app in Site Content, so you’d expect AppUninstalling to be triggered when the app is removed from there. Not so, and here is why: When you remove an app it is placed in the Recycle Bin, so you have to remove it from there too. But AppUninstalling will still not trigger! If you go to Site Settings > Site Collection Administration > Recycle Bin you will see that you actually have two recycle bins. “End user Recycle Bin items” is the one you previously emptied. But there is also “Deleted from end user Recycle Bin”. Open this and you’ll find your “deleted” apps here. Empty this recycle bin too, and now the AppUninstalling event should trigger!

In SharePoint you have two recycle bins!

In SharePoint you have two recycle bins!

Posted in Development | Tagged , , , | 3 Comments

Walkthrough for Animaniacs: Lights, Camera, Action!

When I worked on the GameBoy Advance title Animaniacs: Lights, Camera, Action! we also put together an official walkthrough for the game. The game was however severely delayed, and the walkthrough was forgotten and never publicly released. I found it on my hard drive the other day and though it deserves to be released as intended.

lca_walkthoughDownload the walkthrough

I thought I could also share some more or less interesting trivia about the walkthrough and the development of the game.

  • The walkthrough contains many concept art drawing by Dennis Gustafsson that have never been seen outside the development team.
  • When playing the game you only see a small portion of the map. It’s hard to get the full picture. But the walkthrough shows all maps in the full size! These maps were generated by the level editor we used.
  • Speaking about the level editor, it was custom built for this game by one of the developers, Ola Zandelin. It was later re-used for another isometric game called Looney Tunes: Back in Action. (This game was actually released two years before Animaniacs, which was delayed due to publishing problems).
  • In the walkthrough, all objects and enemies you see are placed on their starting positions. You can also see some objects that are hidden in the real game, but in the editor show up as pink squares. What you don’t see are all the nodes and paths connecting the nodes that we used to control the movements of sprites and other objects, as seen in this screenshot:
lca_level_editor

A typical scene in the level editor. Yellow lines show enemy patterns. Purple boxes initiate events and release enemies & items when the player enters them.

lca_level_editor-04

The same scene without graphics layers, showing the height data. The pillars are used to “paint” the trees on so they appear in front of the sprites.

  • If you look closely at the screenshot you can see that some sprites actually show in front of high backgrounds structures such as trees and walls. Why is that? Well, the game is isometric, a form of pseudo 3D. In order to pull this off on a GBA we took advantage of the hardware layers it offered. These layer could be sorted on top of each other. So walls etc were actually drawn on different layers allowing you to walk behind them. Clever, but not without its problems. For examples, such walls could not overlap, and the background artists needed to pay attention to what layer they worked on or else the sprites would be displayed in front of the wall instead of behind.
  • Between levels in the game you see cutscenes progressing the story, and before each level you also see a “movie poster” for the next level. These all look like images, but actually are not. Instead they is simply a tiny “levels” created with the editor and using the same sprites and graphics as the rest of the game. Besides a convenient way to crate these cutscenes, it also saved us a lot of memory.
The "posters" for the three movies in the game's plot

The “posters” for the three movies in the game’s plot

  • My part in the development team was to place all sprites and create their behaviors. Normally you would use a programming language to do this, but the level editor had a built in scripting tool where I could build behaviors using various pre-programmed actions and states that the script jumped between. It was a very fast and creative way to “program” the enemy behaviors.
lca_script_editor

Enemy scripting

  • The game was released on both GameBoy Advance and GameBoy DS. The DS version does not utilize the extra screen for anything useful though. This is because the this version was an afterthought. The game was developed purely for the GBA, before the DS even existed. It was finished, but due to publishing problems it was never released. Two years later, the game was picked up by another publisher, who hired some other developer to port it to the DS as well.
  • We had a requirement to squeeze the game into a 4MB cartridge. It took a lot of really hard work to achieve this, both with compression algorithms and manual optimizations of content. In the end however, it was released in an 8MB cartride for some reason. Sigh…

Animaniacs: Lights, Camera, Action! did not receive much praise when released. While not the best game ever made, I still think it deserves to be noticed. The plot and dialog is wacky. Graphics and scenery is full of tiny details if you look closely. The maps are big and coherent, and contain lots of hidden areas with bonus items. In all it’s not a bad game. Just not excellent either.

Finally, let me share an unused sprite from the development archives. The idea was to have a “fun-meter”, indicated by a face. It cracks me up every time I see it!

lca_laughing_face

Posted in Games | Tagged , , , , , , , , , , | 1 Comment

Introducing DynForm, a c# library for semi-automatic WinForms dialogs

Application development often involves creating dialogs where the user is presented a form to enter or edit some sort of data. DynForm aims to make development of this a little bit easier. By implementing a simple interface into your data entities, the DynForm library will be able to semi-automatically build a form and display it to the user to fill in.

Update: You can watch an introduction video to DynForm here, courtesy of Kyle Pew at Webucator.

Source Code

You can download the DynForm source code from GitHub. A sample application is included, showing how to use most features. Everything is written in c#. Both the sample and library code is well documented. It is released as open source, licensed with GPL3.

Screenshots

Here are some example screenshots of what DynForm dialogs can look like (taken from a real application):

dynform3

A typical form for editing person details.

dynform2

When selecting items to add to a list, a separate dialog with filtering options is shown.

dynform1

DynForm can validate data and display both errors and warnings to the user.

How to use

Lets say you have a dog entity class:

First add the DynForm namespace to your class. Then add the IDynFormEntity interface and the methods required by this interface:

DynForm is not fully automatic, so you have to tell it what to show in the form. My goal was to make it fast and easy to use, yet still let the developer be in charge of the design. Modify the  SetupFormFields() method as such:

You also need to make sure the data is valid. Modify the Validate() method like this:

That’s really all you need to do in the entity class itself! Now you are ready to display the form. Add this code, for example in a button press event:

The result looks like this (notice that it does not allow you to save the form, since the name field does not validate):

dynform_example

As you can see, with relatively little code you can easily create forms for a multitude of data entities.

Available Controls

DynForm supports many input controls out of the box:

  • Textbox
  • Masked textbox
  • Checkbox
  • Number spinner
  • Date input
  • Labels & headers
  • Dropdown list
  • Listbox

Listboxes are used for more complex situation. Here the user can add and remove items based on a seprate list of available items. Listboxes can additionally have checkboxes, dropdown lists and text fields associated with each item.

Posted in Development | Tagged , , , , , , | Leave a comment