Tuesday, September 6, 2016

Windows IIS and weird cookie expiration

So the authentication cookies served by your lovely ASP.NET site (whether MVC or WebForms) are mysteriously not taking effect in Google Chrome and Firefox, but are, for whatever reason, working in Internet Explorer and Microsoft Edge.

Did you, by any chance, play with your server's (or dev box's) clock recently?

Turns out that IIS can get "stuck in the future", even after you turn the clock back.

After many hours of wasted time, I came across this - and hopefully my little post here and the keywords in it will help you find it much, much sooner and save you hours:

http://serverfault.com/questions/217343/date-header-returned-by-iis7-is-wrong

In short?  Restart the service called "http".  (net stop http, net start w3svc)  Or reboot.

Restarting just w3svc (which I had already tried) is not enough.

Enjoy all those extra hours of you life you just got back!  :)

Wednesday, August 31, 2016

Two-finger trackpad scroll in Slack Windows desktop app and Gmail

You have a Dell laptop running Windows.

Two-finger scroll works in most websites, but sometimes doesn't in Google Chrome (e.g. in Gmail), and never works in the Slack desktop app.

The solution appears to be here, although note that it did not work for me, but then after a reboot some time later, it worked.  So maybe you'll need to fully shut down Google Chrome and restart it, or restart the entire computer, after making the change.

I am delighted to now be able to scroll easily using two-finger scrolling on the laptop's built-in trackpad, in the Slack desktop app, and in Gmail.

Sunday, January 4, 2015

appendChild loses keyboard focus

Scenario : Multi-user editable task list in a web browser, running as a DHTML app.  Changes made by any operator automatically stream to all other operators.  Thus, the task list is frequently being updated by client-side javascript to show changes that have been made by other operators.

Additionally, each entry in the list has an editable text input field that can receive keyboard focus and allow the operator to write notes.

As the contents of the list change, you're likely ultimately going to be using appendChild or a related DOM-manipulation function to ensure each operator has a realtime view of what other operators are doing as they add and remove entries and drag items around to change their sequence.

Turns out, in Firefox at least, that relocating a DOM element causes it to lose keyboard focus.

So for example, suppose Fred is busily typing a note into the text input field for work item #87, and Sally comes along and drags the same work item to reposition it, before Fred finishes his changes.  If we're not careful, Fred instantly sees the updated list order (which is good), but is frustrated because his typing is suddenly going to dev/null (not literally, but you get idea).  Tip : It is bad, bad user experience to steal the keyboard input focus when the user is not expecting it, and most especially so whilst he's in the middle of typing furiously at full speed!  Talk about a good way to destroy the operator's trust in the computer software system!!!  :o)

The solution is simple : onfocus for each input field, record in a global variable (or elsewhere) which input field currently has the keyboard input focus, and then after doing DOM manipulation that might've caused that input field to lose input focus (and assuming the input field is still relevant - e.g. if Sally deleted the work item, well, sorry Fred, your work is lost anyhows), simply invoke mostRecentlyFocussedElement.focus().

And now, your users take it entirely for granted that a) your application works very well; and b) actions by other operators are seen by all operators instantly but without disrupting the other operators.  As I say, the best software works so well that non-technical users will take it for granted and think nothing of it.  This trick is one trick in your arsenal for accomplishing that.

Friday, December 12, 2014

ASP.NET "page has not been precompiled" after publishing


The file '/bla.aspx' has not been pre-compiled, and cannot be requested.


Yeah, thanks ASP.NET!  The site was most definitely pre-compiled.  This very un-useful error message has myriad causes, but for me, 8 wasted hours later, I discovered that at least this time, it was due to use of NTFS compression on my development computer.

Microsoft invented the NTFS compression scheme, so you'd think they knew how to make products that worked well with it..  Or at worst, give an error message clearly stating that use of NTFS compression is incompatible with whatever you're trying to do at the time.  But no, we get useless error messages like the above.

8 extra hours spent on a website deployment that should've only taken 30 to 60 minutes!  It was enough to have me seriously wondering whether I should join the band of happy Ruby On Rails developers!  But then I suspect they have their fair or unfair share of technology gripes too.

My main gripe is that this was what programming was like 20 years ago - extremely unhelpful error messages, things that should work but don't, and many hours and days of wasted time for no good reason.  It is the 21st century now.  We've made so much progress.  Programming is so much easier - by far - than it's ever been before.  But c'mon, we still have stupid problems like this?  Yes, I know, it's a major advance on how things were, but these vestiges of "the old way" have to go.

And as for the particular project I was working on : an extra full day of work for what should've been a simple deployment, might well have cost me a sale.  Not impressed!

If you've published your website using Microsoft Visual Studio .NET (VS.NET) and you chose the option to precompile, and yet are getting this "has not been pre-compiled" message on the server you deploy to, check to see whether any *.compiled files exist in the website's "bin" folder.  If not, then go back to your development machine, and ensure NTFS compression is disabled for the "obj" directory nested within the top-level website project directory - or whatever other location is hosting the files you're precompiling.

Here's hoping you don't lose 8 hours on this stupid bug!

And thanks to a commenter on this blog for helping me find the problem after many hours of searching.

Thursday, December 11, 2014

ASP.NET, symbolic links, and directory junctions

We like to put new versions of live ASP.NET websites in version-numbered folders.

Hitherto, that involved updating the IIS metabase so that the web site or web application "physical path" would point to the new location.

I thought it might be a little easier to use mklink to create a directory symbolic link or a directory junction with a name that I don't change (e.g. "curver" for "current version"), pointing to whatever is the current website version folder at the time.

It doesn't work.

For directory symbolic links, ASP.NET seems to totally fail to use them properly.  Instead of getting the output of each ASPX page when visiting it in a web browser, I get the ASPX source!

For directory junctions, ASP.NET seems to use them just fine, but at the point you update where the directory junction points to, it's hit & miss whether ASP.NET will notice the change or not.  If you're happy to trigger a restart of the website in IIS, then it works but if you're back to mucking around with IIS (i.e. to trigger the website restart), you might as well stick to updating the "physical path" setting of the website.

Conclusion?  It was worth a try - would've been nice if it worked, but it doesn't.

Wednesday, November 5, 2014

Beware: Android Studio ain't all you need

New dev VM, new client, new Android app to build.  Clean O/S install, so I'll just grab Android Studio beta and I'll have everything I need, right?

Would that it were so simple!

The Android Studio download page sure doesn't make it clear that it's just one of many parts to the full picture, and Google searching reveals little.

Most people, it seems, have installed Android Studio after installing the more traditional Eclipse+SDK combination, and in that context, Android Studio works very well.

But on a new machine, if you just install Android Studio, and try to run it, you get an error message stating that no JRE can be found.  Hmph.  Not all-in-one.  Fair enough, but they could've made a note of it in the download page.

So I download & install the Java JDK+JRE, and now Android Studio starts up & looks beautiful.  Yay!  Until I try to create a new project.  Then it complains that the Android SDK isn't found.

Again Google, I'm fine with you not making the Android Studio installer an all-in-one, but could you at least have made it obvious?  Mention on the Android Studio download page that you'll also need to install the Java JRE and the Android SDK!  Then we won't feel somewhat frustrated by having to waste time figuring how to do what was obvious to you, but not necessarily immediately obvious to every one of us.

And this is the general rule, all we developers can learn from, and a rule I see broken over and over again in computer systems of all shapes and sizes : a cumbersome user experience is ok, IF you explain the steps to the user!  But if you have a cumbersome process and DON'T explain the steps to the user, some users will give up, and most users will be frustrated even if they finally figure it out.  And Android Studio is far from the most egregious example.

So my advice?  New dev box, and you want minimal digital clutter but you also want to keep the installation process simple?  Install Java JDK, then install Android SDK+Eclipse bundle, then follow the Android SDK installation page notes about downloading the latest SDK updates, and finally install the Android Studio.  Certainly, Microsoft Visual Studio installation is very polished and absolutely shines in contrast, but hey, we do finally arrive at a working Android Studio, and whilst it did waste time and mental effort, we're there, so I'm moving on, and leaving this "here be dragons" for all ye subsequent travelers.

Tschus!

Monday, October 20, 2014

Inbox zero Gmail hack

UPDATE : Several major improvements on the following :
  1. Create a Gmail filter for an asterisk inside quotation marks - i.e. :

    "*"

    (but INCLUDE the quotation marks)

    The action for this filter should be to apply a label to new messages.  The label should be something like "aaa new" or "0new" or "0" or whatever you choose.
  2. Why the "aaa" or "0" or similar at the start of the label name?  If you're like me, you have dozens of labels, so much so that only a small set are visible in the default Gmail view.

    They are sorted alphabetically, and so putting "aaa" or "0" or punctuation at the start of the label name, means the label will handily appear at the top of the label list, always readily accessible.

    But do note that there is advantage to this label name being short, because the longer the label name, the less of each email's subject line is visible when skimming through newly received emails.  (Of course, if you view the newly received emails by clicking on the label, Gmail is smart enough to not additionally show that label on each email in the list, but I like to have the flexibility to efficiently use this system both from the dedicated label and from the Priority Inbox, which I love.)
  3. Finally, add a pleasant label color to this new label.
Voila!  Now all newly received emails have a little splash of color, alerting you to their arrival, and now you remove the "aaa new" label to indicate you've seen it.  You still get all the benefits of the approach described in the original article (below), with the added benefit that if you remove the "aaa new" label from a conversation, and then a new message arrives as part of that conversation, voila - the conversation is labeled "aaa new" again, which is exactly what we want!

---

I like the idea of looking at a nice, empty inbox, but in practice I find it almost impossible with the state of email management tools today.

Yes, I can tell you how email should work, and that would result in "inbox zero".

But say we're stuck in 2014 and Gmail is about the best we have, and we like the Priority Inbox and Non-Priority Inbox distinction and we want to leave emails showing as Unread until we actually get around to reading them, ...

... but we also want an easy way to sweep older emails out of the way so we can tell at a glance what has newly arrived?

e.g. once or several times daily batch reviewing of new emails.

My first thought was to make a cool custom Gmail plugin.  Nice, but obviously lots of work.  Very nice, but very lots of work.  I imagined having a divider you could drag up or down to mark the point below which you have reviewed emails and above which are emails you haven't yet seen.

Much simpler, of course, would be to make a Gmail label and have all new mail automatically get that label, and then on your daily or other occasional look in your Gmail, search for "label:inbox label:newarrival", or such like.  Once you've skimmed through the emails and are happy for them to disappear from your "new arrivals - not yet seen" list, you bulk select and remove the label.

Or, even simpler to set up, do what I did just now, and create a label called "seen".  As a once-off setup step, bulk select all thousands of emails cluttering your Inbox, and label them "seen".  Now, when you want to find out what emails are new arrivals, search for "label:inbox -label:seen".  Once you've skimmed through them, and left in the inbox anything you want to read later (hence you don't want to mark it read) or otherwise action later (hence you don't want to "Archive" it, which is the only way to remove it from the Inbox), you bulk select them and add the "seen" label to them.

Voila!  Now you have an email system that actually fits the way you use the system - "inbox" means "I plan or hope or would like to do something about this one day", "unread" means "I plan or hope or would like to read this one day", and "seen" means (drumroll) "I saw this email in the list and have determined that it should stay in the list, but I don't need to see it again when I next check for new emails".  And that leaves stars - those oft-abused little creatures - to actually be used for what we intuitively think a star should represent, which is something special, not something commonplace.  Read/unread, inboxed/archived, seen/unseen are commonplace distinctions, and stars have no business representing them.

And that's how I finally got the blissful peace of an uncluttered email "inbox" that works pretty well, and only took minutes to set up, and is trivially easy to maintain - so easy to maintain that I can even easily catch up again in future if I fall behind due to sickness or travel or whatever!  Nice!  Viva labels!

UPDATE : Of course, what this does not give me is notification of new emails added to previously-seen conversations still in my inbox.  That is a problem, although in my particular case, not too great a problem, because a) emails that are likely to be part of ongoing conversations are likely to end up in the Priority Inbox for me; and b) I like the Priority Inbox and still periodically look through it; and c) when a new email arrives for an existing conversation, that conversation jumps to the top of the Priority Inbox.  Altogether, this means I have a good chance of noticing that an older conversation has jumped atop the list.  (Most of the emails I receive go into Inbox not Priority Inbox.)