|
LATEST POSTS
Wednesday, November 28, 2007
So I made it to Part 3. Who knew I had it in me? For the uninitiated, I'm braindumping on my meanderings through the Timok sample application. I'd advise you to check out part 1 and part 2, partially because Part 2 includes a disclaimer that says, now that I look at it closely, don't listen to me. So far, we've followed a request through a controller and how to apply filters to controllers. This time, we're finally going to look at some rendered code. When we left off, we had determined that unauthenticated requests to the main page, /home/index.rails, we're redirected to the Index action on the Login controller. LoginController derives from ControllerBase, rather than SecureController. So it will not run the request through the AuthenticationFilter. Instead, the Index action executes normally. That is, it will use the default layout and the index.vm view. So are we finally rendering something on the screen yet? Why, yes, we are. As mentioned in part 1, the default layout will be rendered with the index.vm view in Views/Login. The HTML you see in index.vm is what is rendered on the page. Sort of. We'll take a look at it now. OK, it kinda looks like HTML but I'm having some acid ASP flashbacks Yeah, and it's not as pleasant as you would have hoped, right? The HTML you are looking at is littered with escape sequences that mean something to the view parser. Like classic ASP, these are processed server-side and the view engine will render appropriate HTML based on the command and its arguments. Note that we are using NVelocity as the view engine. It is the default one provided by Monorail but is not the only one. Brail is pretty popular as is ASP.NET web forms, which has a syntax similar to what you are used to in ASP.NET. I have zero experience with either of them so in the immortal words of Handy: Read a book. In the meantime, just assume that anything with a funky character in front, like # or $, is for NVelocity to figure out. We'll look at a couple of these next. #capturefor(head) The text 'twixt this and the #end block will be rendered in the page's <head> tag. $siteroot Generates a base URL corresponding to the base application. For example, if your application resides at http://localhost/Timok.Rbr.Portal, this URL will be substituted in place of $siteroot when the page is rendered. It is like using ~ in ASP.NET web forms. "$UrlHelper.For("%{action='ForgotYourPassword'}")?username=" + $F('username'); This is a busy little bit of code. First is the UrlHelper which is an NVelocity construct that will create a URL for you based on the parameters passed in.In this case, it will build a URL corresponding to the ForgotYourPassword action. $F isn't actually server-side code. It is rendered as-is in the client. $F is defined in one of MonoRail's js files (AjaxScripts.js). It is a sort of shorthand that says, "append the value of the 'username' form field to this URL when this code is executed. And since we don't know what this will be when the HTML is generated, it has to be a client-side function. It is similar to: document.getElementById('username').value $Form elements These are for various form-related functions. $Form.FormTag generates the <form> tag in HTML while $Form.EndFormTag generates the </form> (along with some validation code). $Form.LabelFor and $Form.TextField generate <label> and <input type='text'> elements respectively. I'll leave it to you to figure out what $Form.PasswordField does. #if($error) This should be somewhat self-explanatory. The HTML in this block is rendered only if the "error" server variable is defined. Summary We finally got to look at some HTML even if it looked a little funny. I sorta skimmed over the funky NVelocity syntax for a few reasons: - It's NVelocity-specific. Brail, ASP.NET WebForms, and other view engines will have their own syntax
- The idea should be familiar to you if you've done classic ASP development, even if the syntax is different
- You can view the source of the resulting page just as easily as I can to see what each of these things does
From here, we'll follow through with the form submittal to see what happens when the user actually does log in. Kyle the Moot
Tuesday, October 30, 2007
Oy vay, the hillbilly has to be more careful adding Part 1 to the beginning of a post. Too many implications about his commitment involved. This is a follow up to a post I did to help guide new MonoRailers through the Timok sample application. If you're just joining us, or have hit me from a random search engine (oh, let's just say it: Google), the intent is to help get up to speed with MonoRail by explaining the steps one might go through when looking through a sample application. I haven't been diving too deeply into the topics because I'm not really a deep-diver by nature, unless it is required. Scared I might get the coding equivalent of the bends. A friendly reminder/disclosure/EULA that, for the most part, I'll avoid any "I think"s and "It looks like"s and "My guess is"es for the sake of readability. Consider this your unqualified qualification that anything I say here is the result of my own investigations with a liberal helping of my previous web experience. When we left off, we had gone through how MonoRail routes requests to an appropriate controller and how that controller determines which HTML to render on the page. We walked through a request to /home/index.rails which led us to the default.vm layout in the Views/layouts folder and the index.vm view in the Views/Home folder in Timok.Rbr.Portal.Web. index.vm contains the HTML that will be rendered within the default.vm layout (akin to a "master page"). But before we div---er, wade into index.vm, we need to back up a bit. I tried to navigate to /home/index.rails but was redirected to a login page. WHAT GIVES?!? Open up HomeController.cs again and notice that it derives from SecureController, which in turn derives from ControllerBase, which in turn derives from SmartDispatcherController. SmartDispatcherController is the main MonoRail controller class and all your controllers must derive from it (or its own base class, Castle.MonoRail.Framework.Controller, but that isn't as common). It's common for MonoRail applications to create their own ControllerBase derivation, similar to creating your own PageBase in traditional web forms. In this case, we also further derive a SecureController class which, as its name implies, allows you to secure access to any controllers that derive from it. How does SecureController restrict access to controllers? The class has the following attributes: [Filter(ExecuteEnum.BeforeAction, typeof(AuthenticationFilter), ExecutionOrder=1)]
This tells MonoRail that before any action can be performed on this controller, we need to first process a filter of type AuthenticationFilter. ExecutionOrder is helpful when more than one filter is applied to a controller, which isn't the case here.
Note that the controllers.config file contains an entry for our AuthenticationFilter class. While the above attribute indicates that we have to use a class of type AuthenticationFilter for the filter, it doesn't say which class specifically needs to process the request. This is another example of how MonoRail uses Windsor, the IoC container. By registering AuthenticationFilter in the controllers.config file, we tell MonoRail "if you need a class of type AuthenticationFilter somewhere and one hasn't been specifically requested, use this one".
OK, fine, so how does *AuthenticationFilter* restrict access to controllers then?
I'm not sure I like your tone, kiddo. Maybe I should just leave you to figure this out on your own, yesno?
No, no, no. I didn't mean it like that. I apologize. Please continue.
That's better. AuthenticationFilter (which derives from MonoRail's Filter class) overrides OnBeforeAction. This code will be executed before any action is performed on a controller that uses this filter. And there isn't anything particularly MonoRail-ish in this code. It checks to see if users are logged in using plain old System.Web.Security.FormsAuthentication. If they aren't, they are redirected to the login page. Or rather, they are redirected to the Index action of the Login controller.
If they are authenticated, OnBeforeAction returns true, which means the request will filter through to the originally requested action (in our case, the Index action on the Home controller). The last line of OnBeforeAction says "return false". The code never makes it this far because it either returns true or redirects to the login page before it gets here. But if it did get to this line and returned false, this tells the controller using this filter that it didn't "pass the test". The controller will then display a blank page which you can verify by commenting out both SendToLoginPage lines.
Summary
Two posts and we still haven't actually rendered anything yet. Yeah, well, security has a tendency of grinding everything to a halt. Here we discussed:
- Applying filters to controllers to execute code before an action is processed
- Deriving your own controller hierarchy
- Using Windsor again to provide a class when one isn't specifically requested
- Being polite to the hillbilly
Next up: We'll finally look at some rendered code and, with luck, what happens when you do something on the page.
Kyle the Insecure
Saturday, October 20, 2007
In my latest effort to pad out my posting count, I'm going to take a sample MonoRail application and annotate it. The reason being: I would have liked one myself. Yes, I can download samples and try to grok it by flipping back and forth 'twixt code and the API Reference Manual. But when I'm looking at a sample app, there are a lot of times I ask "why are you doing it this way?". And there are times where I just plain don't feel like slogging through documentation looking for the section that applies to a specific piece of code. That's about all I'm going to do by way of explanation because this will probably be a long enough post as it is. The sample app I'm going with is the Timok Portal Project prepared by the Castle folks themselves. I considered also the source code for the ALT.NET conference website (or at least a version of it) but frankly, I'm a little scared to say ALT.NET these days for fear that the Pedantic Police will take me away. This little adventure will assume little knowledge of MonoRail other than what it does conceptually. It also assumes you are familiar with traditional web forms and trying to map this new world into what you know. It's laid out as if you are first opening the app and trying to navigate your way through the flow starting from default.aspx. So I will jump around from topic to topic but it's meant to answer questions as they would theoretically occur chronologically. Whenever there are no references to explicit explanations, it is essentially my understanding of how things work. So take it as such. So without further adieu, we'll see how far we get today... Default.aspx Your standard MonoRail default page. It does nothing other than redirect you to the "real" main page: /home/index.rails. It exists because very likely, the IIS directory is configured so that default.aspx is the default page. OK, so let's take a look at index.rails. Waitaminute... It doesn't exist. And in fact, you may also be looking for a home directory off the root. Stop thinking of things in terms of files and directories. If you look in the web.config, there is a section called <httpHandlers>. The first one in the list says that any time ASP.NET finds a URL request that ends in .rails (excluding the query string), process that request with the MonoRailHttpHandlerFactory. That factory parses the URL and decides what to do with the request based on what it finds. And 99% of the time, that *doesn't* involve navigating to and processing an aspx file. To continue from default.aspx, the page redirects you to /home/index.rails. In MonoRail-speak, this means: Find the controller for "home" and process it using "index" as the action to perform. How does it know where the home controller is? Back to web.config. The <castle> section lists references to a bunch of other config files. One of these is controllers.config, which lists all the controllers used in the application. The one we are interested in is home.controller, which refers you to the HomeController class in the web project. How does it know to look at the "home.controller" element? Through the magic of convention and the Windsor IoC container. If you're not familiar with Windsor or IoC, think of it as a way of helping the application to find things it needs when they aren't explicitly provided to it. In this case, Windsor is helping the application to find which class to use when we request the home controller. In this case, it's HomeController.cs in the Controllers folder of the web app, as can be seen from the home.controller component. So where's the HTML that HomeController renders? It may not seem obvious but there are other files associated with this class, similar to how an aspx file is associated with its code-behind/code-beside file. The controller has two attributes attached to it: Layout("default") and Rescue("generalerror"). The Layout attribute tells us which layout to use when rendering the page. Layouts are stored in the layouts folder in the web project. This is always where MonoRail looks for layouts which is why there is no explicit link to the folder from the controller. Layouts are analogous to master pages and I'll leave it at that for now. If you open the layouts folder, there is only one layout: default.vm. Coincidentally, the same name as was used in the Layout attribute of the home controller. (Note: It's not really a coincidence.) So at this point, we have the controller telling us which layout to use to render the page template. Default.vm contains mostly HTML with some "other stuff" thrown in. The only "other stuff" I'm interested in at the moment is $childContent, which is analogous to the PlaceHolder ASP.NET server control in a master page. This is where the individual content goes for each controller that uses this layout. The HTML that goes into that placeholder is located under the Views folder in the web project. Specifically, it is in Views/Home/index.vm. Again, there is no direct link telling the controller to go to this file specifically. Rather, Monorail will look under the Views folder for a subfolder matching the name of the controller. And also note that the name of the file, index.vm, matches the name in the URL we are requesting: index.rails. Minus the extensions. Again, not a coincidence. One final note on the controller. It contains a method called Index which, by this time, should give you some indication that it is important with our request for index.rails. This method will be executed before the index.vm view is rendered. And again, nowhere does it explicitly say, "if you are requesting index.rails, execute the Index method in HomeController". The underlying link in all of this is just the name of the request: index. Summary In our request for /home/index.rails, the following actions were taken: - The request was routed to MonoRailHttpHandlerFactory because it ended in .rails
- The factory parsed the URL to determine which controller should be used to render the request. Using the Windsor container, it determined that we should use HomeController to render the request
- HomeController executed the Index() method, loaded the default.vm layout, and inserted the index.vm view into it and rendered the result.
One of the underlying themes you may have seen is the reliance on "convention over configuration". MonoRail knows where to find things because of the conventions used. Views are stored in the views folder, layouts in the layouts folder. The Index method is executed because we are responding to the index.rails request. Compare this with an aspx page where there is an explicit link 'twixt it and it's underlying code-behind file (via the Inherits attribute on the <@Page@> directive). This is (hopefully) the first in a series because, quite frankly, we haven't covered much yet. Next time, we'll continue where we left off, which is with the index.vm view. But before that, we'll need to talk about why, when you launch the application, you are actually first re-directed to the login page. Kyle the Derailed
Thursday, October 11, 2007
Well, joining the ALT.NET movement has certainly honed my inbox management skills. Thank Allah for GMail's conversation grouping feature. Some good and irrelevant stuff being discussed in the user groups ("good" and "irrelevant" being subjective terms in keeping with the nature of the group). My own reaction has been mostly in line with Master Simser's which has also been espoused by more than a few people. That is, I've reached out to three user groups I've never spoken at before to offer my own brand of down-home, folksy advice as it pertains to software development. I'm already starting to scan, rather than read, the e-mail exchanges which are focused on the group's identity. Not sure why people are so hung up on it, especially since we've got all of one conference under our belt. But if everyone was as passive as I am, I suppose there wouldn't have been a conference in the first place. In any case, that's not what I came here to jaw about. Much has already been said on Microsoft/Scott Guthrie's MVC framework. And during the conference, more than one person asked, "what does this mean for Monorail"? The fine folks of Castle apparently have been asked this question as well because when I wandered over to their website (looking for Monorail documentation), I found a nice little reaction specifically to that question. And it was one that I expected them to make: choice is a good thing and we'll be looking at how to integrate it with the rest of our products. 'Tis a good time to be a software developer. Jay the Schizophrenic
Friday, September 28, 2007
Three days after my nervous breakdown and lo! i am saved! Both my mind and spirit (still working on my body). If you recall, Launchy, SlickRun, the WinKey, and even Alt+Tab were not working on my remote desktop connection because I had to launch remote desktop within the context of a Citrix application. Launchy has been re-enabled simply by disabling it in my laptop. I suppose that means that since Alt+Space isn't handled there, the keystroke is passed into Remote Desktop. Frankly, I don't care. I can find things again! WinKey is still insistent about not entering into my remote desktop. But SlickRun is back by nature of AutoHotKey. Which brings me to... AutoHotKey's status has been bumped from "great utility" to "the most awesome computer application ever invented". Thanks to it, I have remapped SlickRun to RightCtrl+R. More importantly are the following two lines I've added to the AutoHotKey script: RControl & RShift::AltTab RControl & Enter::ShiftAltTab
This is taken directly from the AutoHotKey documentation. What it means is that I can Alt-Tab my way through applications by holding down RightCtrl and repeatedly pressing RightShift. Ditto for going the other direction by pressing RightCtrl and Enter. And since I rarely use the right Ctrl, Alt, and Shift keys, there is little chance it will interfere with, say, a ReSharper shortcut I use. Hello keyboard, my old friend! I'm free to type on you again! Kyle the Re-invigorated
Wednesday, September 05, 2007
Quick nugget o' information today 'cause I'm still on the clock.
MbUnit has a couple of command line parameters I've been using lately: filter-namespace and filter-type. Both can be useful when you have several hundred tests and don't want to run all of them when you're working on one area of the app.
The informational nugget: when you use either of these parameters, it will include tests marked with the Explicit attribute in your test run. Assuming, of course, those explicit tests are included in the filter.
Kyle the Filtered
Thursday, August 30, 2007
Having been having a merry old time moving projects around in our solution in Team Foundation Server. We had a few that had strayed from the folder where they were supposed to live and we can't have free-thinkin' VS projects now, can we? Anyway, there was a bit of a learning curve involving more than one rollback. Plus I coined at least three new words and phrases but it's all good now, as the kids say. So forthwith is my guide to doing the same in your project (as in your software project, not your Visual Studio project, rather your Visual Studio solution, I'm...ummm...rambling, aren't I).
Underlying guidelines:
- One at a time. Don't try to get cocky and move all your projects in one shot. You'll save yourself days of pain if you move them individually within one "check-in" session. (OK, maybe not *days* of pain but certainly precious minutes.)
- Rebuild and run your tests often. After you re-add your projects, before you check in, after you re-get the latest version, pretty much every second step of the process.
- If at all possible, make sure everyone has checked in pending changes, *especially* if they have stuff checked out in one of the projects you intend to move.
Now to the heart of the matter:
- Make sure you have the latest version of the solution and have nothing checked out.
- Rebuild and run your tests.
- Remove the project from the solution. TFS should check out any projects that have a reference to the one you just emasculated.
- Physically move the project to where you want it to be in Windows Explorer.
- Re-add the project to the solution. It will be marked as "not under source control" which is a bit of a lie.
- Loop through each project in the solution checking to see if it has been checked out. This is your indication that the project has a reference to the one you just moved. Re-add the reference to the moved project.
- Re-build and run your tests.
- Open the "Change source control" dialog. (Alt-F, R, O)
- Unbind the project you just moved and click OK. It should be easy to find as it will be marked as Invalid.
- Add the project back to source control. (With the project selected, Alt-F, R, E.) With any luck, TFS should add it in the appropriate path, adding any necessary folders along the way.
- Re-build and run your tests.
- Check-in your changes.
- Re-build and run your tests.
- Open the Source Control Explorer (from Team Explorer) and find the project in its old location. Delete it and check-in your change.
- Re-build and run your tests.
- Repeat ad infinitum.
One thing to watch out for is references to third-party assemblies. When I re-added our data access project, the compiler complained about a couple of NHibernate methods not existing. I dropped and re-added the NHibernate reference and they went away. If I had to guess, I would say that I have an old version of NHibernate in my GAC which the project tried to use after I moved it.
Kyle the Gatekeeper
Thursday, August 30, 2007
While we're on the topic of tools, I'll voice my concerns over two that I've been using regularly over the last two months.
Notepad++ There are two specific annoyances that bring me to tears in frustration. First is the tabbed interface which I have never liked. Not in Firefox, not in Internet Explorer, and certainly not in a text editor. I like to Alt-Tab through my apps, not Alt-Tab to the one I want, then Ctrl-Tab to the page I need. There's a reason Word and Excel aren't MDIs anymore. (Yes, yes, I know. You know what I mean.) Plus I like to see the titles of the documents I'm working on in the task bar. Visual Studio is an exception.
Peeve number two: There's no default extension when you save files. If you know of a way to set a default extension *and* turn off tabbing, I will quickly recant but at present I see no way around either issue.
UltraMon Before I lay into UltraMon, I do still love the product. My beefs with it are not enough to shy away from the $40 price tag.
Both issues have to do with expanding Visual Studio across both monitors. I do this with Visual Studio so that the code appears in one monitor and all the other little windows (Properties, Solution Explorer, etc.) are in the other. I do this through judicious use of docked windows and careful placement of splitters.
When I lock the computer, Visual Studio is squished back into a single monitor. What's worse, when I click the button to Maximize to Desktop, the splitter controls have moved so that the code, which previously filled only the entire right-hand monitor, now extends about an inch into the left-hand monitor. And when your sysadmin has set a five-minute screen saver with password protect on, this hillbilly is in the market for an app that automatically moves the mouse around every four minutes and fifty-eight seconds.
This is happening only for Visual Studio, not other apps like Excel or Outlook so I imagine it's not UltraMon's fault. And I've gotten around it by not expanding VS across both monitors but by maximizing it on one, and undocking the tool windows so they can roam free on the second.
Side note: There are complaints on the UltraMon forums on: a) the price tag, and b) the lack of updates. Neither concern me but you may want to look through them before making your decision. If only for a laugh.
Kyle the Tooled
Tuesday, August 28, 2007
Who says you can't teach an old hillbilly new tricks? Have finally made Launchy ubiquitous (or as we say in the Ozarks, you-bet-we-duz) to the point where I'm looking for a way to get rid of the Start button on my task bar and free up some real estate.
But chances are, you all know and love Launchy already. And you probably are aware of the plug-ins, Weby and Runny. The first tells Launchy to open the browser of your choice when you type in http://www.welovesquirrels.com/. The second lets you create shortcuts to applications that typically take arguments.
Side note on Runny. It's possible to use it to launch apps that *don't* take arguments but you have to press Tab then Enter to launch the app. The developers recognize this as being a little quirky but can't really do anything about it. It is because of this (and the funky way you need to specify paths in Explory) that I still use SlickRun for some things.
What I aim to edify y'all about is that there have been recent updates to both Weby and Runny. Weby has the most interesting one as it now allows you to create shortcuts to parameterized URLs. And by default, you get parameterized shortcuts to almost everything you'd need, like Google, MSDN, Wikipedia, and IMDb. You even get an e-mail shortcut: mailto:$1 which opens a blank message to a specified e-mail address.
I've made a couple of tweaks to their default list:
- Shortened the Google shortcut to just "g"
- Added "?subject=$2" to the e-mail shortcut so you can specify both a recipient and a subject
- Added a shortcut to http://www.$1.com/ (using "w" as the shortcut). This lets you type: w, <Tab>, firefox <Enter> to go http://www.firefox.com/. I'll leave it as an exercise to create your own shortcuts to .net and/or .org addresses.
If I have one complaint about Weby, it's that it doesn't handle URLs that don't start with www very well. You always have to type in http:// at the beginning. Luckily, that's where Runny comes in. I've bound the following application to "i":
- %PROGRAMFILES%\Firefox\firefox.exe $1
The result is I can get to my own blog easily by typing: i,<Tab>,kyle.baley.org,<Enter>. At work, which is a little more draconian in their blocking rules, I have something similar set up for IE. Note that you'll need to use quotes in that case: "%PROGRAMFILES%\Internet Explorer\iexplore" $1
Kyle the Aborted
Wednesday, August 01, 2007
Have been using AutoHotKey for some time now after a brief fling with HotKeys. You may have read about AutoHotKey over at LifeHacker or scanned it at Scott Hanselman's Ultimate Tools list. But neither do the tool justice. Both claim it is an auto correct tool you can use outside Word but that's not entirely accurate. While the utility can be used for that, it's only a small part of the warm fuzzy feeling that is AutoHotKey.
At a higher level, it's a way of automating pretty much anything using keystroke combinations. And I do mean anything. You can even map the Caps Lock key to something else or even cancel it altogether (which is more than the useless key deserves). And if you were so inclined, I imagine you could remap your keyboard so that it became a Dvorak one instead of qwerty.
I downloaded it initially so I could map various actions to Win key combinations but imagine my surprise when I stumbled on to a fully-functional sample script that lets you use the number pad as a mouse replacement. And a fully customizable one at that. You won't be playing Halo with it but it's definitely workable for, say, opening the little Outlook new mail notification, or having to deal with a non-keyboard friendly webmail app in IE. (Having said that, that particular script does have a slight quirk when you are running dual monitors.)
A quick scroll through the script showcase should give you an idea of what's possible. To me, it seems like the tool brings the power of ReSharper shortcuts to every other application on your machine. Of course, you have to put in the time to figure out how to write the scripts which can be pretty daunting for even relatively simple macros, let alone one that will display a list of favorite folders when you click the middle mouse button in certain types of windows.
But I admit the more advanced features are left untouched by me as yet and for the time being, it remains only a Win key mapper. Current mappings:
- Win+R = SlickRun*
- Win+S = Visual Studio
- Win+O = Outlook
- Win+P = Paint.NET
- Win+N = Notepad++
- Win+C = command prompt
- Win+1, Win+2, Win+3 = various remote desktops I commonly use
- Win+D = My Documents
- Win+F = Facebook (Oh, admit it, it's in your favorites too)
* The app appears to override the GrabWinR feature you can use in SlickRun so I had to add an mapping back to it. Unfortunately, the Chase Cursor option no longer works but I can live with that.
Kyle the Mapped
Wednesday, July 18, 2007
Like its creators, I've abandoned WinKey. Whether or not it sticks has yet to be determined but I think it will thanks to the fine folks at QLiner. Some time ago, I tried their HotKeys application, a Win key mapping application, and discarded it based on two things:
- Minor confusion when the on-screen keyboard would disappear after releasing the Win key
- No support for Shift+Win, Ctrl+Win, or Alt+Win
The first issue has been addressed in that you can actually launch the on-screen keyboard as an application albeit it appears you can do it only through a Win key combination mapped from the application itself. There be no way to launch it externally as far as I can see. But it's not like I'd actually try to look for it from the Start menu.
The second issue is still outstanding but after a year with WinKey, I can honestly say, I have never used the Win key in combination with Shift, Ctrl, or Alt.
So with both impediments removed, it was time to take another look at the product and see what they've done in the year since I last saw it. The interface (and indeed, the website itself) is still pretty, almost Mac-like, which is probably not an accident. I like the drag and drop support if you want to shift shortcuts around. And it still has support for niceties like volume control and Control Panel applets. And best of all, it's still free.
But that's still not all. There are two new things that have really piqued this hillbilly's interest something that hasn't happened since the last family reunion.
Both are technically add-ins to the product but they are included with the base install. The first is support for zipping and unzipping files. As in, you press Win+1 (or whatever you've mapped it to) to zip selected files and Win+2 to unzip them. No more right-clicking and navigating to WinZip | Unzip to current location. It's all done with the keyboard now. (This is especially nice at the place where I'm working now where they've eschewed any third-party zip tool in favour of the not-so-esthetic Windows XP default extractor.)
The second is screen capture support. I haven't given it my full attention but it seems rudimentary compared to others. Still nice to have it as an option only two keystrokes away.
There are a couple of downers: I've managed to hang the app a couple of times in the short time I've had it installed. (The zip features, despite my raving, seem particularly buggy.) And the on-screen keyboard doesn't always refresh promptly (or at all). This is particularly true if you open the keyboard, switch to another application that covers it even partially, then switch back to it. The visual cues are all gone even though it still works as expected.
Also, it takes over your default Win key maps. Not too big a deal since it overrides them with the same functionality. But I was a little surprised to see the Run dialog appear for Win+R rather than SlickRun. And for Win+E, it doesn't actually open a new instance of Explorer, it switches to the existing one (if open). And if there is more than one instance open, it cycles through them. Very annoying but apparently will be addressed.
Finally, due to the flashy UI and the fact that it's a .NET app, it's not exactly what one would call a lightweight app. There are complaints about that in the forums and rumblings that the devs will switch to something more portable. Regardless, I don't care much given how many other .NET apps I'm running at any given moment.
Overall, my second impression is very positive. It still kind of surprises me that tools like this don't get as much press as, say, SlickRun or Launchy. Those two are still great and one or both will always be installed on my computer but there is no comparison 'twixt typing Alt+Space, then "vs", then Enter to launch Visual Studio versus typing Win+S.
Having said all this, I'll be using AutoHotKey instead.
Kyle the Expedient
Friday, June 08, 2007
While I will profess my undying love of ReSharper, I do have a bit of an annoyance with its auto-closing delimiters (as explained here). I've talked before on my love of white space but it comes with a price. Whenever I type the opening parenthesis of a method, ReSharper helpfully adds the closing one. It's also smart enough to recognize when you type the closing one yourself and won't duplicate it if you do so. If you don't have a space there, that is. Here's an example. Let's assume I type the characters: "this.gethashcode(" without the quotes. Here is how it looks right after I type the (: this.GetHashCode( )
ReSharper has helpfully added the closing parenthesis and even respected my choice of using white space after opening parentheses and before closing ones. The problem is that the cursor is now situated right after the first parenthesis and I need to Right-Arrow or End my way to type the closing semi-colon. And neither key is situated in an area that lends itself to quick access on my laptop. If I type the closing parenthesis, ReSharper does not recognize that this is the same as the one it just helpfully added (the way it does when there is no whitespace). So I'm left with: this.GetHashCode( ) )
(Note: I added the space after the first parenthesis manually. It's a habit I'm hoping I don't have to break.)
There is a way around this that I haven't quite got into the habit of using. That is to take advantage of ReSharper's advanced IntelliSense. Here's what appears when I start typing GetHashCode:
At this point, I can press <Tab> and get the following: this.GetHashCode()
Plus the cursor is sitting helpfully at the end of the line. And no worries about my precious gestalt. I need only type the closing semi-colon and either ReSharper or Visual Studio will format it into the beacon to gestalt I am looking for: this.GetHashCode( );
The problem with this method is that it kind of slows me down. I find it much faster just to type "gethashcode(" than to start typing "get", search through the list for the one I want, arrow down if necessary, and press Tab. My way has more keystrokes to be sure, but does not require that I pay attention to the UI.
The habit I'm trying to get into is: rather than typing "gethashcode(", instead type "gethashcode<tab>". Theoretically, this should be easier...
Kyle the Habitual
Monday, May 14, 2007
If there is one thing my compulsive mind does not like, it's seeing little Chevrons on my Quick Launch toolbar. Especially since it also usually means there's a new icon on my desktop that I need to delete. Y'see, hillbillies like'un to keep their desktops orgie-nized. And to do that, I like to know what's on it. Which means I like to decide what goes on it. And I don't need the likes of Apple, Microsoft, Adobe, Nero, or anyone else using it as a dumping ground for a piece of software I may not even keep, let alone use enough to warrant an easily-accessible icon. The screen I love to see most in an installation is: Do you want an icon for <my app> on your desktop? WinZip is masterful at this, asking not only if there should be a desktop icon but if they should even *create* a program group for it in my Programs menu. And the answer is no. I can no longer remember the last time I actively sought out the WinZip application, if I ever did. That's what the context menus are for. Apple is a particular thorn in my side on this issue. Not only did they not even ask to install icons in the Quick Launch bar and the desktop, every time I get an update from them, I have to delete these things all over again. And there is simply no reason for me to have them. I have never, ever opened QuickTime directly to do anything. Oh, I've viewed my share of .mov files. By double-clicking them. Why would I need an icon (or even a program group) for it? Apple, of all companies, should recognize this and give me the option not to add the icons. I'd make the same complaint about Acrobat Reader but I went one better on Adobe. Not only did I delete the icons and program groups, I also deleted the application itself in favour of Foxit Reader. But it is a textbook example of an application that needs no icon. Anywhere. My Quick Launch bar is sacred ground. Yes, it shouldn't be necessary with the likes of SlickRun and WinKey but I still use it for applications I open sporadically, if not regularly. Until I can spare the twenty-six seconds it takes to set up a magic word or hotkey for them. Until then, lay off my Quick Launch, QuickTime.
Tuesday, May 01, 2007
Sweet Jayzus, I have to reveal my ignorance more often if this is going to be the result. That's a faster turnaround than at your average Bahamian bank check-in counter! So, James, I hate to mention it for fear of looking stupid but I'm having a little trouble writing this tiny piece of software to predict the stock market....
Wednesday, April 11, 2007
Plethora of postings today. Could combine them but I'm trying to stick to the Single Responsibility Principle, at least in one small aspect of my life. Doesn't seem to work while I'm parenting the young 'un. Have recently started working with Subversion. Out of necessity because I want to share code with someone and it's harder to share when you're in the Bahamas. (That generally applies to everything in the Bahamas, especially in the government.) First thing I did when installing Subversion was to add TortoiseSVN and AnkhSVN to my tool list. Hillbillies aren't generally what you would call command line coders. Like most side aspects of software development, I don't have a very strong opinion on source control. The only thing I want is for it not to get in my way. In that respect, I liked SourceSafe while still recognizing that it was the one piece of software that Microsoft actually *needed* to update in the last ten years. Having said that, I haven't had any horror stories that many, many others have and checking in/checking out was pretty seamless from Visual Studio. Now comes Subversion where I am painfully aware of the source control because it's throwing errors all over the place. Well, probably not Subversion but certainly Tortoise and definitely Ankh. Errors like "the directory already exists" and "this is not a working copy of the directory". When it wasn't failing, it was creating folder structures I didn't want or adding support files to source control. (Don't get me started on ignore lists. Sometimes I want to ignore the bin directory, sometimes I don't.) Granted, part of this is a shift from my comfort zone. I've managed to get to a point where I can create a Subversion repository and folder structure I like and not have one overwrite the other. I'm also able to mangle Ankh enough to add another project to my solution without polluting it with ReSharper files. But even today, I'm not able to Update... my solution with Ankh because it says the lib object already exists. "lib" is a folder that contains my third-party tools. It's not even part of my solution. Having said that, when it's on, it's really on. Fast and clean be Subversion. Especially over HTTP. But it's not exactly an "install and go" type application. And it's better than SourceSafe. I say that mostly to keep my inbox free of hate mail because in reality, I don't care if it is "better" or not. It's just source control. I just want it to work.
Wednesday, April 11, 2007
The Coding Hillbilly loves typing as you can tell from the fact that he types out "The Coding Hillbilly" rather than using the short form, "I". But that's neither here nor there, whatever that means. Part of my recent PD has been going more in-depth with various N-based tools than I have in the past. The one I'm going to discuss is NCover because that's the one that has caused a problem interesting enough to talk about. The problem occurred when trying to run NCover from a NAnt script. It would reach the end of the unit tests, then hang for approximately 120.58 seconds before failing. The issue was documented in a forum somewhere and the recommended fix was to add registerProfiler="false" to the <ncover> task (which I prefer solely due to its aesthetics). I did that and lo! Then I went on vacation, took a different computer, and did a download and build. Same problem. Eventually, I ended up switching to the <exec> task which worked. Until today. Now both versions are hanging, seemingly on the profiler. The odd thing was that NCoverExplorer worked fine with the same profiler. So I used it to generate my <exec> task and lo! The difference 'twixt the NCoverExplorer generated task and my task: The NCoverExplorer one referenced ncover.console.exe in C:\program files, mine referenced it in tools\ncover. The version in the former was 1.5.7.0, in the latter 1.5.4.0. Copy the newer version to tools\ncover and lo! Know not why this is an issue and, as is my policy, I don't care much. This falls under the realm of infrastructure, which isn't my strong suit. All that matters is that the problem is solved and documented so that I may find the solution again in the future when it happens again and I inevitably forget the solution and have to find it on Google.
Thursday, April 05, 2007
Sweet NJayzus, there be a lot of tools out there for a .NET developer. And the Coding NHillbilly has finally gotten around to doing an ninventory of them on his machine and collecting them into one place for quick and easy nmanipulation on his nlaptop. And might I suggest to fledgeling tool developers that you forego the apparent nstandard when naming your gift to the nworld. I...errr...mock but this is something I've given some thought to. Down in the Bahamas, acronymic company and product names are the norm. Which in some sense is good because the actual names are so generic, you need an acronym to tell one from the other. Some examples: Data Systems International (DSI), Computer Information Services Ltd (CIS), Micronet, International Private Banking Systems (IPBS), Custom Computers. These names may be somewhat descriptive but frankly, they're boring as hell. I tried for eight solid months to get the creators of IPBS to change their name to Flamingo but they weren't having none of that. So put some thought into your company/product name. But don't get hung up on any hidden meaning of the actual word(s). It's not like people will even think about the company name past the end of your introduction. If you're good enough, the name will eventually come with its own connotations apart from the word's underlying meaning. To wit: Java, Sun, Amazon, Google, eBay, and almost any car name you can think of (what exactly does "civic" mean anyway?). I installed Rhino.Mocks over NMock based on its name alone. Various members of my family have long owned companies named Suvius. It's a name I love. Yes, it has some relation to Mt. Vesuvius and if you want to draw connections to the power of volcanos, go blow it our ear. I like it because it rolls off the tongue easily, it's a (semi-) made up word, it has lots of round letters (which makes for nicer logos), it starts with the same letters that it ends with (bonus: they're reversed), and if you want to get REALLY touchy-feely, it ends with "us". Eventually, I'll get the name of the company in lights but until then, it's just a cool-sounding word to me. Semi-related sidenote: My dad and brothers are now the owners and operators of a fast-growing land surveying company called Trilogy Surveys. The reasoning behind the name? We liked the sound of it. As luck would have it, they've bought out another company called Lennon Surveys so now they get to call themselves Lennon Trilogy. Here's hoping they don't get the wrath of Yoko descended upon western Manitoba...
Tuesday, August 15, 2006
Just had a new Dell laptop delivered and before I start, let me throw out a pre-emptive "don't bother" for anyone thinking of adding some colour commentary on how Dell is crap. I buy Dells. Deal with it. What I'm going to talk about today is not unique to them.
So I started the long and arduous process of migrating from my old laptop to the new one. Why does this suck so? Why hasn't someone invented None Hardware-Specific Ghost yet? Why do I have to spend nigh on five days to get everything just right again?
The first order of business: The OEM crap has been removed, in some cases surgically. This consists of AOL, MusicMatch, WordPerfect, Learn2 Player, McAfee suite (seriously, folks, I might consider keeping your software on my machine if it didn't expire before the milk in my fridge did), etc, etc, and so on and so forth. Despite the fact that none of this stuff seems complicated, I did need to reboot about half a dozen times to get rid of some of it.
Next comes configuring Windows XP to do what I want. This includes installing IIS, configuring Windows Explorer, IE, start menu, and task bar options and adding the Address bar, Control Panel, Admin Tools and Desktop to my task bar.
Next up: locate all the free software/tools/utilities I've started to take for granted. Here's a list that's probably not complete but is off the top of my head:
- Firefox
- AVG Anti-virus
- Defender
- Spybot
- SlickRun
- WinKey
- .NET 2.0 (why is this not standard yet?)
- Paint.NET
- Notepad2
- Acrobat Reader 7.0 (had to remove version 6.0 first; I have a love/hate relationship with versions 5 and 6)
- TweakUI
- CmdPromptHere
- WinZip
- SmartFTP
- NewsGator for Outlook
- TextPad
The last two aren't free but I have licenses for them and they are small enough utilities that I like to include them here.
Then comes the development and productivity tools like Office, Visual Studio, SQL Server, etc, etc. Finally, there is the configuration of all previously mentioned software. Importing MagicWords for SlickRun, setting up shortcuts for WinKey, setting up my folder structure for NewsGator, the MANY settings from TweakUI, importing Visual Studio settings. (NOTE: Does anyone know a way to copy my safe senders list from one Outlook instance to another?). None of this stuff is as "one-click" as they say it is.
After that is about a day's worth of Microsoft Updates. Then the easy part: copying over my actual documents, databases, projects, etc and dealing with any other clean-up (like attaching the databases).
I thought maybe I could create an installation package for at least all the free tools but this involves a crucial step: I need to update the installation whenever I discard or adopt a new tool. Ditto if I keep a backup of my mammy's raccoon pie recipes.
There are other methods but from what I've seen, they all suffer from the same problem. I don't buy new laptops often enough to justify the time it takes to maintain on ongoing update process.
So I know I said keep your opinions to yourself when it comes to my choice of laptop vendor but the rest of this post is fair game. Am I missing out on something that could free my time to go badger baitin' with my cousin-brothers?
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent
my employer's view in any way.
Copyright © 2008 Kyle Baley. All rights reserved.
|
|
|
LATEST POSTS
POPULAR POSTS
LINKS
BLOG ROLL
|
|
CATEGORIES
ARCHIVE
| December, 2007 (8) |
| November, 2007 (8) |
| October, 2007 (23) |
| September, 2007 (15) |
| August, 2007 (8) |
| July, 2007 (6) |
| June, 2007 (11) |
| May, 2007 (19) |
| April, 2007 (14) |
| March, 2007 (3) |
| February, 2007 (4) |
| January, 2007 (7) |
| December, 2006 (5) |
| November, 2006 (9) |
| October, 2006 (11) |
| September, 2006 (14) |
| August, 2006 (11) |
| July, 2006 (15) |
| June, 2006 (8) |
| May, 2006 (10) |
| April, 2006 (12) |
| March, 2006 (3) |
| February, 2006 (7) |
|
|
|