Automatic NAS Box shutdown – How to execute applications on Windows Shutdown (Part 2/2)

In Part 1 we looked at how to figure out what message was being sent from the web management page of my Netgear ReadyNAS Duo network storage box, and then how to replicate that to happy from a c# dot net console application. To finish this off, we now need some way of making that new console app run automatically when I shut down my Windows 7 PC.

I started in the Task Scheduler panel in Control Panel > Administrative Tools.

On the right hand panel you can then select “Create Task…”. From this dialogue you have a number of tabs along the top- the second one along, right after General is “Triggers” – switch to this and then hit the “New…” button which brings up a third window called “New Trigger”.  From the drop down list entitled “Begin the task:” check the selected option from the default “On a schedule” to “On an event”.  So you should now see something similar to this screen shot;

At this point I was kind of stumped- The other options in that “Begin the task:” list were things like “At log on”, “At startup”, “On work station lock” etc – there was no “On Shutdown”!! So I selected “On an event”. This gives you three new options in Settings – Log, Source and Event. From here it was down to taking an educated guess. I knew that shutting down Windows was likly to be logged as a “System” event, so in the first drop down I selected System.

What to choose in the Source drop down was not so clear- so to decide on an event source to use, I opened the Event Viewer, again from Control Panel > Administrative Tools. From the left hand panel, I opened the “Windows Logs” branch, then from within that selected “System”.  These are arranged by time, so it’s just a matter of going back to when you turned your computer on today, then going back a couple more to see the last things your computer logged before turning off when you last used it.

In the end I opted for the event shown in the above screen shot- by reading the description I noticed it mentioned shutting down explorer.exe (a main component in Windows) because of the “power off of computer”, which I figured, with out knowing the in’s and out’s of what this really meant, sounded pretty promising. So from the same window I noted the Source “USER32″ and Event ID “1074″.  Going back to the New Trigger window I found that USER32 did indeed appear in the list, so I selected that and entered 1074 as the event ID.  This is pretty much everything for the trigger, so hit ok, then move on to the Actions tab, and click “New…”

From here it’s pretty easy- the action we want is to “Start a program” then just use the browser button to find the program you want to run. Click OK and return to the General tab.

This final step may not be required, but I did it anyway just to be sure- on the general tab, I changed the radio button at the end and selected “Run whether user is logged on or not”. I also changed the “Configure for:” drom down at the bottom to be “Windows 7, Windows Server 2008 R2″. And that’s it- Shut down your computer to give it a go. If you are following on from my previous post and you pointed the action dialogue to run the .exe produced from the last post, you should see your computer shut down and then a few seconds later the NAS box will power down.

Drop me a comment if I’ve missed any critical details!

You can see the finished app here

No Comments

Automatic NAS Box shutdown – How to POST the shutdown command over SSL with HTTP authentication from a dot net Console app (Part 1/2)

I recently purchased a Netgear ReadyNAS Duo RAIDed network storage box for general backup of my ‘stuff and things’, which sit’s on my desk and runs off the same power as my PC.  A couple of times now I’ve booted the box up to run a backup, then forgot to shut it down, then shut down my PC, flick the switch at the wall and then realise.  When I boot everything back up in a day or so, the NAS box has to do a full system check and maybe rebuild the RAID array if theres a problem etc etc – it’s a pain.

So I thought I would set about automating the NAS box shut down with my PC shut down which turned out to be pretty easy.  The NAS box is controller via a web UI- my box has the host name “BACKUP” so I can get to it over the browser on http://BACKUP/.  This uses basic HTTP authentication asking me to login, and also use’s https (which my browser always warns me about because it’s not from a trusts CA or whatever- so I just ignore the warnings and continue).  From the web UI you can go to the system tab and select shut down and the box goes down.  I figured as this is going to be a simple web call, it should be easy enough to write a simple console app which makes the same call which can be fired on Windows shutdown- so I fired up Firebug, opened the “Net” tab, which allows you to inspect all http calls made, and triggered a shut down. It’s probably worth noting at this point that the techniques used here could probably be applied to pretty much any other networked device with a web based UI (most routers, firewalls, switches, printers, media boxes etc) so this should hopefully be quite useful.

Sure enough the HTTPS POST made to a file called get_handler on the root could be seen, with the POST data string;

As we can see from firebug, the data sent is;

PAGE=System&OUTER_TAB=tab_shutdown&INNER_TAB=NONE&shutdown_option1=1&command=poweroff&OPERATION=set

So six key value pairs separated by ampersands.  The code itself is pretty simple using WebClient class (System.Net namespace)- however there are a couple of complications, which as it happens are fairly common things to run into, so a good opportunity to give some example code for future reference;

  • We need to perform our Form Post over SSL

  • The SSL certificate of the server we are posting to will never be valid!

  • We must carry out our form post while supplying basic HTTP authentication credentials

I created a new Console application and added the following code;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;

namespace ShutdownNASBox
{
    class Program
    {
        static void Main(string[] args)
        {
            using (WebClient client = new WebClient())
            {
                // add the basic http authentication username & password
                client.Credentials = new NetworkCredential("admin", "abc123");

                // register the face that the connection uses SSL
                // (otherwise it defaults to TLS and you get an exception)
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

                // set it to effectivly ignore the SSL certificate
                ServicePointManager.ServerCertificateValidationCallback =
                                                        delegate { return true; };

                // build a NameValueCollection which holds those 6 values we saw
                // being posted when we used firebug
                NameValueCollection c = new NameValueCollection();
                c.Add("PAGE", "System");
                c.Add("OUTER_TAB", "tab_shutdown");
                c.Add("INNER_TAB", "NONE");
                c.Add("shutdown_option1", "1");
                c.Add("command", "poweroff");
                c.Add("OPERATION", "set");

                try
                {
                    // Post the data!  This will return as a byte array
                    byte[] bytes =
                    client.UploadValues("https://backup/get_handler", c);

                    // convert the byte array into text we can read!
                    string result = Encoding.ASCII.GetString(bytes);

                    Console.Write("Shutdown Message Sent");
                    Console.Write(result);

                }
                catch (Exception e)
                {
                    Console.Write("Shutdown Message Send Failure!");
                    Console.Write(e.ToString());
                }
            }
        }
    }
}

And that’s all there is to it! An obvious and easy upgrade would be to make this parametrized and maybe get it to write to the windows log on failure.

In part two I shall do a quick post on how to schedule tasks to run on shut down in Windows 7.

You can see the finished app, with the above recommended improvements already implemented, here

, , , ,

No Comments

Android app will not fill the screen on Tablet

I’m just starting my first Android app, which allows users to draw to the screen. So accomplish this, I’m not using a normal xml layout file which is then “rehydrated”, but instead I’ve just created a class which inherits from View which deals with drawing the user input to the screen. I fired up a new project in IntelliJ IDEA and created my view and the classes which would run the app based on the html5 canvas/javascript prototype I’d put together a little while earlier. Everything worked well except the application only filled about a quarter of the screen when run on my Xoom tablet, despite me not actually having specified any screen sizes or limitations.

The solution, after some googling, was fairly simple- in the manifest you need to specify the minSdkVersion to be at least 4, as prior to this, varying screen sizes was not supported. I added the following to the bottom of my manifest file;

<uses-sdk android:minSdkVersion=”4″ />

3 Comments

Entity Framework “The data reader is incompatible with the specified complex type.”

I recently had this problem with a site I’m working on. I’m using Entity framework to access a bunch of legacy stored procedures, originally in MySQL but ported over to MSSQL. Having added the sprocs to EF and let it auto-generate it’s magic, I was shocked to find one of my calls throwing the following exception;

System.Data.EntityCommandExecutionException: The data reader is incompatible with the specified &#39;ChinookModel.GetVehicleDescFromModelId_Result1&#39;. A member of the type, &#39;ivaluationid1&#39;, does not have a corresponding column in the data reader with the same name.
   at System.Data.Query.InternalTrees.ColumnMapFactory.GetMemberOrdinalFromReader(DbDataReader storeDataReader, EdmMember member, EdmType currentType, Dictionary`2 renameList)
   at System.Data.Query.InternalTrees.ColumnMapFactory.GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType, Dictionary`2 renameList)
   at System.Data.Query.InternalTrees.ColumnMapFactory.CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, Dictionary`2 renameList)
   at System.Data.Query.InternalTrees.ColumnMapFactory.CreateFunctionImportStructuralTypeColumnMap(DbDataReader storeDataReader, FunctionImportMapping mapping, EntitySet entitySet, StructuralType baseStructuralType)
   at System.Data.EntityClient.EntityCommandDefinition.FunctionColumnMapGenerator.System.Data.EntityClient.EntityCommandDefinition.IColumnMapGenerator.CreateColumnMap(DbDataReader reader)
   at System.Data.Objects.ObjectContext.CreateFunctionObjectResult[TElement](EntityCommand entityCommand, EntitySet entitySet, EdmType edmType, MergeOption mergeOption)
   at System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, MergeOption mergeOption, ObjectParameter[] parameters)
   at System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, ObjectParameter[] parameters)
   at Chinook.Model.ChinookEntities.GetVehicleDescFromModelId(Nullable`1 modelid) in C:\_Dev\Chinook\Source\Chinook.Model\Chinook.Designer.cs:line 160
   at Chinook.Model.GlassGuideDataProvider.GetVehicleFromModelId(Int32 ModelId) in C:\_Dev\Chinook\Source\Chinook.Model\GlassGuideDataProvider.cs:line 104
   at Chinook.Services.VehicleDataLookup.GetVehicleForRegistration(String reg) in C:\_Dev\Chinook\Source\Chinook\Services\VehicleDataLookup.asmx.cs:line 81

It seemed to be moaning that one of the columns in the complex type I set for it to use as the return type, doesn’t match to a column actually being returned, despite entity framework having auto generated that type itself! The cause was, as is generally the case, user error. Inspecting the sproc a bit closer I noticed one of the columns was being returned twice, using the same name. EF generated me a call with an iValuation and iValuation1 column, but failed to match iValuation1 because in reality both columns were simply called iValuation! So a simple, and kind of obvious fix, but worth noting to stop someone else loose a little more hair when they’re confonted with this error!

No Comments

Powershell folder/ sub folder renaming

I had my first go at powershell today to rename a bunch of folders in a way which I figured would be too fiddly at the standard command line.  I had a bunch of log files in a structure like this;

/RootFolder
  /foldera
    /logs
      /a-random-log.txt
      /some-log-file.txt
  /folderb
    /logs
      /a-file.txt
      /b-file.txt

I basically wanted to recurse each folder and give the files a sensible name, with a view to eventually moving them all into one folder- so I wanted this;

/RootFolder
  /foldera
    /logs
      /foldera-1.txt
      /foldera-2.txt
  /folderb
    /logs
      /folderb-1.txt
      /folderb-2.txt

After some fiddling I came up with this, which I ran straight from the power shell prompt, in the root folder location;

Get-ChildItem | foreach { $id = 1; Get-ChildItem (($_.fullname) + “\logs\”)| foreach { Rename-Item -Path $_.fullname -NewName ($_.Directory.Parent.name + “-” + ($id++).toString() +”.txt”) } }

  1. Get-ChildItem grabs a directory listing of the root folder- the resulting array I then pipe into a foreach loop.
  2. Each iteration of this first loop I reset the counter variable I will use for naming the files.  Then I grab an array of the files inside each of the log folders within the folders I just listed (!) — so this should be a list of the files in foldera/log/ and folderb/log
  3. Finally I perform the rename – I build up the new file name based on this file (the $_ represents the current object in this iteration of a foreach in powershell) directory property (which will = logs) then I do .parent (to grab the parent dir of logs) which gets us to the directory name we actually want.  I string this together with the index number and hard code an extension, as I know all my files are .txt files.

It took a little fiddling, but it was nice to finally use powershell, as there are many people bigging it up on various tech blogs and twitters!

Once I’m this far, the move is just a matter of tweaking what I already have a little..

Get-ChildItem | foreach { Get-ChildItem (($_.fullname) + “\logs\”)| foreach { Move-Item $_.fullname -Destination ($_.Directory.Parent.Parent.fullname) } }

 

Useful; To find the properties available to you, pipe your collection to Select-Object *, which will iterate through each element, giving you a full print out of all of it’s available properties, and their current values.

No Comments

Front end web developer coding standards

Well put together, and generally good advice about the finer details of javascript (closures, truthy values) for someone starting out.

http://taitems.github.com/Front-End-Development-Guidelines/

No Comments

Adding Javascript Unit Testing/ Compression to your MSBuild

A couple of resources- I shall add to this post as I look into this myself.  I basically want to add steps to my project file, so msbuild will run javascript tests (qUnit) and perform minification/ combines all the js source files.

No Comments

Quickly Find/ Open a file in Visual Studio

I’m working on some massive solutions containing loads of projects at my new place and frequently have to shoot between different source files scattered all over- A colleague recently showed me a really quick way to find and open files- from the Find bar in the top ‘standard’ menu bar, you can type ‘>of’ followed by the name of the file you are after and it will bring up an auto complete menu letting you select and open the file.

No Comments

Javascript profiling in IE7…

…cannot be done with the built in dev tools, as I reminded myself today.  I guess my memory painted a fonder picture of the first version of the IE debugger than it deserved.  I’ve been using the IE8 debugger a lot of late as I’m working on a very JS heavy UI targeted primarily at IE users, which has some firebug-esque features, like break points/ profiling etc and I foolishly assumed such things were always there, because a web debugger without these tools wouldn’t be much use..

Anyway turns out all is not lost- after wading through a bunch of rubbish solutions I eventually found  an awesome profiler (for free, of course!) which works with IE 6, 7 & 8!  Check it out- “DynaTrace AJAX Edition

1 Comment

Javascript development on Cloud9… unless you’re on Windows :(

Update 2011.03.03
@rikarends from the Cloud9 team was nice enough to chat to me on Skype about my windows woes and I’m reliably informed that the Windows chunk of Cloud9 still needs a little polishing and will be up to scratch in a future release; you can follow them on twitter for news (@Cloud9IDE) – in the mean time older branches from GitHub should run fine (v0.2.0)- in the mean time you can always run their most up to date version from their hosted service at http://c9.io


Very excited to try out a new HTML5 IDE for Javascript launched this week called Cloud9- you can sign up for an account and hosting, in much the same way as GitHub, however you can also download the project to run locally via NodeJS.

I did have some trouble with this though- I ran git command to download the project to my computer, no probs, then ran the run batch file (I’m on Win7 x64) and this ran about half way then died with this little beauty;

Failed to recurse into submodule path 'support/ace'

:| All looked a bit bleak for a moment- did a bit of Googling and found other people had had this issue- dug through the launch script and found the command that gets fired on first time launch which seems to get a bunch of support packages from Git- this seems to be what failed- I CD’ed into the cloud9 folder and manually re-ran that get

git submodule update --init --recursive

And it seems second time’s the charm- everything finished downloading– that’s not to say I got it running!  Also found a problem in the batch file which starts it up in bin/cloud9-win32.bat – the use of EQ on the if conditions broke the script so I adjusted line 9 to;

IF NOT %ERRORLEVEL%==0 goto exit

and line 18 to;

IF %ERRORLEVEL%==0 goto exit

Now it manages to make it through the script only to say

E:\cloud9\cloud9>bin\cloud9-win32.bat
------ Starting Cloud9 server ------
"Something failed unfortunately, please try a clean clone"
Press any key to continue . . .

Digging into the script once more the command which gets fired to launch it is;

start support\node-builds\win32\node bin/cloud9.js -a "cmd /c start"

So I launched this without the “start” at the command line and the underlying error is;

E:\cloud9\cloud9>support\node-builds\win32\node bin/cloud9.js -a "cmd /c start"
2 Mar 21:05:17 - socket.io ready - accepting connections

                           Ajax.org Cloud9 IDE
                              version 0.2.0
Project root is:
Trying to start your browser in: http://localhost:undefined

So port undefined is obviously no use; I mod the batch script again to specify a port- in bin\cloud9-win32.bat line 16 I change to;

start support\node-builds\win32\node bin/cloud9.js -p 3000 -a "cmd /c start"

This sets the default port to 3000 and relaunching the batch file actually now fires it up- but still it doesn’t work. The browser lauches and I can see bits of the top menu from the UI- however in the accompanying console window I get spammed with errors such as;

Error: Command failed: execvp(): No such file or directory

    at ChildProcess.exithandler (child_process:80:15)
    at ChildProcess.emit (events:27:15)
    at Stream. (child_process:148:12)
    at Stream.emit (events:27:15)
    at Array.0 (net:1004:12)
    at EventEmitter._tickCallback (node.js:55:22)
    at node.js:772:9

I give up! If any one gets futher, please drop me a comment!

9 Comments