views:

546

answers:

10

If I wrote

1) a C# SQL database application (a simple program consisting of a GUI over some forms with logic for interfacing with the SQL database)
2) for home use, that doesn't do any network communication
3) that uses a simple, reliable, and appropriate SQL database
4) whose GUI is properly separated from the logic
5) that has complete and dependable input data validation
6) that has been completely tested so that 100% of logic bugs were eliminated

... and then if the program was installed and run by random users on their random Windows computers.

Q1) What types of technical (non-procedural) problems and support situations are most likely to occur, and how likely are they?

Q2) Are there more/other things I could do in the first place to prevent those problems and also minimize the amount of user support required?

I know some answers will apply to my specific platforms (C#, SQL, Windows, etc) and some won't.

Please be as specific as is possible.

Mitch Wheat gave me some very valuable advice below, but I'm now offering the bounty because I am hoping to get a better picture of the kinds of things that I'm most reasonably likely to encounter.

+7  A: 

It never ceases to amaze me what real users will do. Get ready for anything and everything.

kenny
The solution is to not have any users! ;P
leppie
"Make it idiot-proof, and someone will make a better idiot."
jleedev
@jleedev reminds me of idiocracy. I like software! http://en.wikipedia.org/wiki/Idiocracy
kenny
+13  A: 
  • Never Trust Unvalidated User Input

  • Build great error logging (and possibly an error auto-submit feature) into your Application. Have the ability to increase the logging level dynamically, so that verbose logging can be turned on at a user's desktop.

  • Report errors to users in a friendly way; don't blame them!

  • If your application is dependent on many environment settings or third party addins/libraries that might be changed by other software, consider running an initialisation step that checks for and logs expected and found versions. This can save you pulling out hair!

Mitch Wheat
Great point. What do you mean by "increase the logging level dynamically"? Thanks.
ChrisC
@ChrisC: I mean being able to change it from a normal 'Errors only' level to a verbose 'log everything' while the user is using the application. That way you can diagnose problems 'live'.
Mitch Wheat
Use a logging framework like log4net. http://logging.apache.org/log4net/
Mike Atlas
By "live", do you mean using a live connection from my pc to theirs? If so, that situation wouldn't be possible. Therefore, if that's what you meant, would it be good to either have a button the user could push to enable verbose logging when told to do so, or just have it on all the time (and delete logs older than x days)?
ChrisC
@Chris C: probably not on 'verbose' all the time; maybe have an user option somewhere. As @Mike mentioned, log4Net is what I was alluding to and should have said explicitly! (thx Mike)
Mitch Wheat
@Mitch, noted, thanks.
ChrisC
Would the downvoter please leave a comment. Thanks.
Mitch Wheat
Sorry, Mitch. It was an accident, and now it won't let me change it.
ChrisC
@ChrisC: I will edit the question. Then if you like you can remove.
Mitch Wheat
And......fixed.
ChrisC
I would have said this, but passing unvalidated input along is, as far as I'm concerned, a logic bug :)
kyoryu
+6  A: 

Q1) What types of issues would still come up?

Bugs, design flaws, feature requests, and usability problems, same issues as any other application.

Q2) How much time and knowledge would resolving those issues require?

More than you want to spend.

Q3) What things could I do in the first place to minimize the amount of user support required?

Tests, tests, and more tests. Hiring full-time testers is the best thing. Otherwise, make sure you set up a support database for yourself so you can easily look up past issues and pass this knowledge onto other support staff.

Use a good bug tracking/ticketing system, preferably one that lets you expose or integrate with some sort of user-accessible knowledge base. If you're lucky, that will help cut down on a small number of support requests.


If you want to be really proactive, build a behaviour-tracking system (preserving user anonymity, of course) into the application, so you can see what features users spend the most time on and understand the areas where your mental model of the app does not jibe with theirs.

Oh, and try to make the program fail gracefully. A cryptic exception dialog helps no one; have a screen that explains at a general level what went wrong and what they can do to solve it ("try again in 30 seconds", "restart the application"). Some unexpected error conditions actually can be dealt with this way, such as connection timeouts. Make the same screen have an option to either automatically submit an exception report or copy the debug info to clipboard so they can e-mail it. Your job will be a lot easier if you have a stack trace.

In one of my apps, I modified the global exception handler to display a special message for certain kinds of network timeouts and it drastically cut down on the number of timeout "bugs" submitted. As long as you track exception reports, over time you'll learn which types of unhandled exceptions/unexpected conditions come up frequently and be able to... well, handle them.

Aaronaught
A1) Like what, assuming my 1-5 points are true, specifically? A2) Obviously, that's why I wrote the question. Q2 asks for info pertaining to A1. A3) My #3 point stressed testing, but the Answer DB is the kind of info I was hoping this question would produce. Thanks.
ChrisC
@ChrisC: I don't think any of us could possibly speculate on the *specific* requests that will come in for your app without knowing *specifically* what it does and how it works, from top to bottom. You've only said that it's a GUI with a database back-end, which describes probably 90% of in-house corporate apps. If it were possible to predict these things then we would all be putting out perfect bug-free software. ;) All you can do in this industry is expect the unexpected, design for testability and maintainability, and build a good support team with good support tools.
Aaronaught
Just to give you one example of something you can't predict: The user has a flaky network connection (i.e. wireless) and various operations intermittently fail. You'll get all sorts of different bug reports from different areas of the app and you'll have to sort through which ones might be important.
Aaronaught
I appreciate your input, but I think the assumption may have been made that this a business app that accesses a network. It isn't like that. It is just a C# app that acts as a gui with some logic to use for inputting and querying data in a sql db. It doesn't need or use anything networked.
ChrisC
@ChrisC: I'm not making any assumptions, I simply stated that there are thousands, probably tens of thousands of apps that fit your profile, all of which are radically different and will have a completely different case list. Some of us have tried to give general advice on what to expect and how to handle it but it is simply not possible to predict exactly what's going to end up in your inbox. Who knows, maybe their computer gets infected with a worm and you start seeing all sorts of bizarre reports. You just don't know, you can't know, if you could then our jobs would be a lot easier.
Aaronaught
+1  A: 

We had a customer once that didn't want to use the software, because of the fear that the software will replace him.

He used a forklift to crush the pocket PC that the software was running on.

Pierre-Alain Vigeant
Did it result in a support call? ("My Pocket PC seems to be flatter than usual today")
Aaronaught
yeah, the pocket pc was a hardened one. A Teklogix. They called us because the battery did not want to fit back in "after they recharged it".
Pierre-Alain Vigeant
Good thing it didn't replace him first!
kenny
Silly @kenny, pocket pc's cant drive forklifts!
AviD
I don't know about the pocket pc, but my droid tells me where to drive, so I figure it must know how, no!?
kenny
+4  A: 

If you're asserting that your logic is correct and validated (per your question) that leaves basically state-based issues to deal with.

So, the things you'd have to worry about would include:

  1. Hardware failures

  2. Critical files being nuked on the machine at unexpected times, and not by your program.

  3. Dependency updates that break you.

  4. Overall system state - things like the hard disk getting full

  5. The database being stopped

  6. Dependencies getting uninstalled

Also, any place in your code where you assume that an external process is running and available is just a problem waiting to happen. You should always assume that any external process is flaky, and that it going down arbitrarily is expected behavior (that's part of why you have things in separate processes). In fact, relying upon any state that you do not completely control is inherently risky. While you can get overly paranoid going down this road, it's good to at least consider what you're depending on, and being very careful and explicit about what you make assumptions about (probably safe to assume the .NET framework is around, as if it's not, it's probably beyond your scope to fix that issue).

kyoryu
Thanks, kyoryu. This is the type of info I was hoping for. How should I prepare for and handle those things happening? Would my dependencies be only .net and the sql db? Are there any external processes that my program would rely on, or that would affect it?
ChrisC
@ChrisC: It depends on your app - I can't really tell you what your dependencies are. As far as what you should do to handle them - to a great extent, that's up to you. Users can break your app no matter what, by doing bad things. You can't stop that. It's probably better to have a reinstall/repair story than to watch all dependencies. As far as weird crashes and whatnot, the important thing to do is to always assume that failure can happen where you least expect it, and do everything possible to avoid corrupting persistent state. Failures happen, but are okay. Corrupted data is BAD.
kyoryu
Thanks, kyoryu. I am getting most of what you're saying and I appreciate it. I know I'm new to this, but is there not enough info in my question to be able to tell what dependencies my program would have? If not, what others could it have, for example? Also, does "reinstall/repair story" mean a good, reliable way to reinstall/repair program files got deleted/corrupted? And, could you give me an example of something that can be done to "avoid corrupting persistent state"?
ChrisC
@ChrisC: Make sure that, by running the installer app, you can get back to a good state if your existing state is trashed, that's what I mean. That kind of brute force approach is almost always necessary at some point, even if more clever appraoches are useful some of the time. As far as avoiding corrupting state, any time you write something to the disk/db, think about what could happen if your app crashes in the middle of that operation.
kyoryu
@kyoryu: Can you point me to examples of things that can be done (for C#/sql programs) to prepare for the inevitable time of a hardware failure during a disk/db write?
ChrisC
Well, SQL does a pretty good job of handling that by itself, so long as you wrap everything appropriately in transactions. It's when you make multiple calls to the DB sequentially, not in a transaction, that you need to worry.
kyoryu
Mmm. Ok, gotcha. And since the only part of my program that changes is the db, the brute force installer/fixer would handle any corruption of program files, etc, caused by a hardware failure? Can you tell from my description if I'd have any other dependencies (other than Windows and .NET) to be concerned about?
ChrisC
This is a good answer given the difficulty of the question, but based on what I've seen so far, I can't help thinking that he plans to use these points as an excuses for bugs. "Oh, you're getting an error message there? Must be a hardware problem."
Aaronaught
@Aaronaught: My only concern of the question is "assuming my logic is completely bug-free".... I've never seen that actually happen for any program more complex than "Hello, World".
kyoryu
@Kyorku, don't get sucked into aaron0's mental pit. I purposely phrased my question that way so that I didn't get a bunch of "you'll have to fix the logic bugs" answers, and instead would get answers that pointed out other types of problems that I'd see.
ChrisC
@ChrisC: No worries. I understand the framing now - you're not saying your code is perfect, you want to know what you have to worry about *outside* your code. #1 is assuming that anything that's not your code actually works - files get deleted, the network dies, etc....
kyoryu
Exactly. In other words, my question asks: ignoring code logic problems, what problems are most likely to happen, for a program like the one described?
ChrisC
A: 

The biggest problem you will encounter is a DUMB/AIRHEAD/LAZY user.

Luiscencio
+1  A: 

Forcing a user to install Microsoft SQL Server Express is a huge dependency. I would recommend using something more light weight like SQLite.

Also, if you don't heed my advice and use SQL Server, then please make it configured so that it will only accept connections from 127.0.0.1

For making the whole process easy on the user, use as much scripting as possible for the installation. Don't try to force the user to configure some complex piece of software to work with your application. Make sure they have a 1-click default install that works just like that.

Earlz
Thank you, Earlz.
ChrisC
+2  A: 

First, if you are building a Windows app, you need to account for the fact that everyone's Window's installation is going to be different. Some might have additional security applications running. Some might have UAC on; some off. Different OS's, different OS patches installed. Some users might only be in the Users groups; others in the Administrators group. Just getting users to have the needed .NET framework installed properly could be a challenge if their system is partially fekawied. In addition, you are going to have machines with different physical capabilities. In short, you need to be careful about making any assumptions about what is on the user's machine.

One thing you can do to reduce the change of security software getting in your way is to develop your application to run with the most restricted level of trust permissions as you can muster. Look into .NET trust levels. The more restricted trust levels under which your application will run, the lower the odds that some other security feature or application will balk at its usage. In addition, you should get a full code signing certificate to sign your assemblies.

Another decision you should consider is your use of the database engine. While SQLExpress is nice, it creates an installation maintenance issue for the type of application your are proposing. What if they have an older version installed? What if they have a new version installed? What if the version you are using requires a patch? What if their security software stops the service from running? You haven't mentioned how much data would be involved in the application, but you might consider a more portable database format like SQLite or even Jet (Access) (although Jet has other issues with which to contend) just to avoid having to install yet another service on the user's machine.

As you have stated, minimizing user support is the big issue with something that will have numerous installations. As others have suggested, in order to cut down on support calls and help you make corrections to the application:

  1. Testing. Specifically, automated testing both unit and functional. 75% of the code written for this app should be test code.
  2. Logging. In addition to a mechanism to log errors, you are going to need to build a mechanism that allows the user to ship those logs to you for troubleshooting.
  3. Rock solid installation routine. You need to make the installation as bullet proof as possible. If users cannot install your app, they can't use it. So, along with testing on your app, you'll want extensive automated testing on the installation routine. Ideally, your app would be so encapsulated that it could be deployed via xcopy.
Thomas
Thanks, Thomas. Does using SQLite avoid all those versioning issues you mentioned that could come with using SQLExpress?
ChrisC
The versioning would be wholly encapsulated into the versioning of the app unlike say SQL Express which can be upgraded or versioned independently of your application. Thus, if a new version of SQLite was released, it would your decision to upgrade rather than the users.
Thomas
Thanks, Thomas. Up vote from me. Regarding your comment about having the installation "so encapsulated that it could be deployed via xcopy". Could that really be possible with my c#/sqlite app (assuming the user's computer already had .net on it)? Will VS Express write c#/sqlite app that uses no registry entries? That sounds like a good thing. Can you tell me a little bit more about that?
ChrisC
@Chris - Yes. SQLite was designed to run with zero installation. There are .NET ports of SQLite which work great. You can use it from VS Express just as you can use any third-party library by adding a Reference. Using Google I quickly found: http://brennydoogles.wordpress.com/2010/02/26/using-sqlite-with-csharp/. Using Jet is also possible and also has the same advantages of zero installation. My problem with Jet is that it is possible for the db to corrupt itself on occasion which would make for a support headache.
Thomas
Thanks. On the same subject, will I be able to configure my program so that it actually could be installed with only xcopy? (not that I would deploy it that way, but that would mean no registry entries, etc). (the program is just going to be a sqlite db with a C# ui.)
ChrisC
You should with one caveat: the proper version of the .NET Framework. Ensuring that the user has the proper version of the .NET Framework would be the one reason for creating an installation routine presuming that your application could otherwise be deployed via xcopy. If you use a port of SQLite to .NET, then no other dependencies should exist and you can use it just as you can write an application to write to an MS Access mdb without having MS Access or anything other than the Framework installed.
Thomas
Sincere thanks for your replies and your help, Thomas.
ChrisC
I'm glad I could help. Good luck on your app!
Thomas
@ChrisC: If your app can be installed with just xcopy, you remove an entire range of problems that you might have. Essentially, anything in your app that isn't xcopy-deployable is an assumption that you're making about the state of the system - and as I pointed out in my answer, assumptions about the state of the system introduce fragility. If you can't assume you can write a reg key at install, then your program, *by definition*, will have to deal with the case that the reg key isn't there.
kyoryu
So you guys are both saying that, assuming that .net is installed and running properly on a target pc, my c#/sqlite program should be able to be installed by only copying files/folders?
ChrisC
Correct. In fact, you can go beyond that by using a feature called clickonce deployment to make it so that the user need only go to a page and click on a link to get your app. When you do that, your app runs in a restricted trust environment which is why I also suggested designing your app so that it could run in this environment.
Thomas
Btw, another solution is to simply use SQL Server Compact edition. It has most of the features of SQL Server and again requires no installation (i.e., it can be deployed via xcopy).
Thomas
+1  A: 

In my experience of 20 years, the most common problem in your scenario is not about building the software wrong, but about building the wrong software.

What I mean is that it's quite likely that, as you introduce the software product into the users' routine, this routine changes. If it didn't change, your sowftare would be a failure, since that would mean it didn't have an impact (i.e. no added value). So, assuming it does change the users' environment, we can also assume it will change the users' needs, and therefore their requirements, and hence the suitability of the software product itself.

By definition, a successful software product is doomed to turn an awkward fit after some time. In my experience, this happens every single time, and there's not technology or method that can go around it. :-)

CesarGon
Very interesting, CesarGon. Thanks for the reply. Upvoted.
ChrisC
You're welcome. :-)
CesarGon
+2  A: 

I started writing code in a spare bedroom in 1988 and built a company essentially typing on a keyboard and answering calls. Since we're still growing 20 years later, I guess you'd say we've done pretty well. I don't take tech support calls very often any more but I pick up the tech line every once in awhile just as a way to stay in touch with customers.

What follows is a kind of compendium or classification system for the most common calls that I've taken over the years. Your results may vary but the list should give you some insight.


The most common class of complaint that I've seen over the years dealt with the installation of the application. I went through enormous effort to automate every aspect of the installation but people still have trouble.

  1. Inability to Follow Instructions: Some people just won't follow instructions and they'll call you when things don't work. For example, the installation of our app has three steps (database server, database and application). Despite very clear instructions, some people will do just the third step because they have some theory as to why they don't need 1 or 2. Workaround: use a professional installer (e.g. InstallShield) to simplify the process as much as possible. InstallShield and Wise both had tools that offered an amazing array of tools for dealing with almost any contingency. They are pricey but well worth the investment. The simpler the better - assume nothing and you'll minimize your calls.

  2. Database won't install: There are some computers that simply will not run the SQL Server express installation. No good reason why, they just wont. There is no good workaround although you will want to make sure you aren't just seeing an instance of case #3...

  3. Database already installed: Some people will already have SQL Server (in some form) so your install won't work. Workaround: use a named instance with a unique name.

  4. Installer doesn't have privileges: The person attempting the installation can usually figure this one out and will go for help to the group that administers the computer. So this one isn't common. Workaround: No good workaround to avoid the calls altogether but you can keep them short by simply explained that you don't have the ability to override the restrictions placed on them by their Admin so they will need his or her help.

Despite these experiences I would not hesitate to recommend that you use SQL Server and .NET even for a moment. The number of computers that won't run SQL Server has become vanishingly small (if was worse in the late 90s, early 00s) and I've never had trouble installing .NET. It is a great database for local applications and it lets you evolve if you ever want to scale up.

The next class of calls comes from people who simply have a different model of the software than you do.

  1. Metaphor Confusion: Our software uses a "Folder and Page" metaphor interface and is widely lauded for its ease of use. But some people used to just got confused by all of the selections we provided because they had a very simple model of what they were looking to do. Workaround: I built a multimedia demo into the help system and the "Getting Started" topic explained the user interface metaphor. Calls on the topic dropped to zero.

  2. New Feature Requests: you'll also have a significant number of calls from people who want new features but who, surprisingly, express their desires by telling you that you have a "bug" in your software because you don't support their desired feature! Workaround: Listen! Whenever I got a request from two different people OR I really liked an idea, I built it. I was very aggressive about this. In the end, people loved the product, loved the business, and recommended us to friends. I often say that our business is built by the ideas of our customers (even if they are cranky and unreasonable sometimes).

  3. Needs More Detail: Our software offers a broad range of fitness tests that people can perform. At the beginning, we used to field a lot of questions about the tests themselves, the source of our information about the tests, etc. Workaround We built a complete description of our tests and their source into the help system. The broader lesson is that your help system isn't just about how to use your software. It is a very important means for communicating directly with your customer about the whole range of processes that you are trying to automate! It won't eliminate all of the calls but they are a lot shorter when you can say: "just open the help system and click on topic X."

  4. Found a bug: You may believe that you have no bugs but it isn't very likely. Users do strange things to software and they will call when they get an error message for doing things they should be allowed to do. Workaround: Have a method for recording bug reports (I can recommend FogBugz!) and be aggressive about fixing them. Of course, you'll also need a means whereby clients can upgrade their systems easily or your fixes won't be much help. Most of the commercial installation packages have tools that permit you to post updates on the web for automatic download and installation. If you want to be successful, though, you must listen to users and respond to their pain.

The next class of support calls comes from people that are moving to a new computer.

  1. Moving a Database: People don't know how to back up a database (even if you provide a tool) and they'll often be scared to even try because their data has now become too precious to risk. Workaround: We created a number of very highly detailed documents dealing with these tasks and posted them on our site. It didn't eliminate the calls but it reduced them significantly.

  2. System Crashes: "My computer suddenly died in a puff of electric sparks. The hard drive has been making loud grinding noises for months and I never made a backup because I didn't feel like it. How can I get my data back?" Workaround: Only one - have a good sense of humor and remind them to make backups.

The next class of support calls that we deal with are those related to the license.

  1. Registering: Will someone using your application need to register? Even if they can do it online, some will call you anyway. Why? In 50% of the cases it is because they want a free copy and want to tell you a lie to get it. The other half aren't connected, have an unexpected message, are moving to a new computer, etc. Workaround: None, these are people who are just determined to talk to you so they can use the app even if they have to have brass balls to do it.

  2. Honest People: Some honest people will call you just to ask whether it is Ok to do one thing or another (can I use this on my laptop?) or because they aren't supposed to do something but they hope you'll let them do it anyway. Workaround: Make your license as clear as possible - especially in the first few lines since that's all they will read.

  3. Finally, there are fans. People who just love what you do and who want to talk to the company that built it. This is less common now than in the 90s but they are the most fun to talk to. No workaround there, just enjoy it while you can.

Good luck building your business!

Mark Brittingham
Thanks Mark, huge answer. Upvote from me. So I notice that you don't mention a some of the problems that others have mentioned. Things like updates to Windows or .Net that break the program, full disks causing problems, or "Critical files being nuked on the machine at unexpected times, and not by your program". Do you not see these things very much?
ChrisC
Chris - I am reporting what I see and all but one of the issues that you list simply haven't occurred...ever. They are kind of textbook things that should screw up your program but, in practice, no one calls on them. Windows will warn you if your disk is filling up, .NET updates have never been a problem (and I wouldn't expect them to be), critical files being nuked - doesn't happen or, at the least, people don't call about it. - continued -
Mark Brittingham
The only one that I *have* seen is a problem when an older customer tries to move to Windows 7 or Vista. That one is a pretty easy catch though. Since our older software used the MSDE (which isn't compatible with Vista/7) we just route these calls to the front desk for disk replacements. Two other notes: almost all of these people are moving to new computers so they are mostly covered under my "Moving a Database" topic. Also, moving from Vista to 7 simply has no effect; I cannot think of a single call from someone who upgraded to 7 and then had a problem (or a service pack, etc.)
Mark Brittingham
@Chris - btw - we do field about 4 calls per day / 20 per week / 80 per month. So our sampling isn't huge but it certainly isn't trivial - especially when you stretch it over 20 years. Keep in mind too that we've driven these numbers way down over the years by using the workarounds I discussed above.
Mark Brittingham