Offsite backups with Windows Home Server and Crash Plan

I have been slowly moving files onto my new WHS.  HP is due to release a new software version that allows for users to easily backup their shares to Amazon S3.

I have done a lot with Amazon’s S3 service, but I don’t feel good about using it for backups for a few reasons.  Primarly, if you want to backup large amounts of data, it IS very cheap, but it is sill kinda expensive.

In other words, it is very cheap compared with other managed storage options, but if you want to backup 500 GB you are still going to be paying a lot of money over the course of a year.

The solution I came across, which appears to be working fine on the WHS machines is Crash Plan (crashplan.com).  I installed it on my WHS and on the WHS I bought for my parents and have configured the 2 to backup to each other.

I won’t get into all the details, but Crash Plan:

  • costs nothing for the basic version
  • encrypts your files before they leave your machine
  • sends you emails if a backup has not happened successfully in X days

I have found no problems with running it on WHS.  I even replicate the files crashplan backs up across multiple drives so if my house burns down AND a hard drive at my parents fails, my data will still be safe.

Performing a Baseless Merge in TFS

If you create a branch in TFS, you can easily merge it back later, but if you have 2 branches or folders that you want to merge, but are not related (they weren’t branched from one another) you need to do a baseless merge.

This article describes the process:

http://msdn.microsoft.com/en-us/library/bb668976.aspx

But the short end of it is that you run the following command at the VS command prompt:

tf merge /baseless c:source c:dest /recursive

It will launch the dialog box for you to manage the merge from there.

Has RJDJ been removed from iTunes?

One iPhone app that I really like is RJDJ.

http://rjdj.me/

It is very hard to explain it, but it basically takes the sounds around you that it picks up through the mic, and does all kinds of weird stuff to it to make beats/sounds/music etc.

It’s really fun, and every single person I have shown this too has loved it, except for 2 people, and they are brothers, and they know who they are.  But everyone else has totally loved this program.

Unfortunately, many users felt that, once they paid the giant price ($2.99) for the full version of RJDJ, called RJDJ Album, that they would get future songs/scenes for free.

Instead, mostly due to how Apple restricts developers in how they can charge for stuff like content/udpates, they released the 2nd “album” RJDJ Shake as another $2.99 app. 

Some users were pissed, and I think they logged enough complaints to have RJDJ removed from iTunes, which totally sucks because I wanted to buy Shake and now I can’t!

I wanted to put this post out there so if anyone else was trying to figure out why they can’t get RJDJ they might get some answers here.

I hope the folks at RJDJ get this resolved, b/c I think it’s an awesome program.  When I get some free time I am going to program some scenes for it, but right now I am spending all my free time on work for my clients.

UPDATE: It’s back.

Streaming Audio From WHS

I have been looking into some of the options for streaming music from my WHS to devices in my house.

So far I don’t seem to be finding many good options.  There are some that you point to a UNC share and then have to deal with a crappy UI to select the songs you want.

2 of the nicer options I have see are:

http://www.sonos.com/howitworks/

 

 

and

 

http://www.roku.com/products_soundbridge.php

 

 

 

http://www.roku.com/products_soundbridgeradio.php

 

 

I’m going to have to keep my eyes open for other options, but these seem like viable candidates.

 

Learning Spanish In Cancun Mexico

I recently had an opportunity to travel to Mexico for some spanish lessons.  I wanted to put up a little write up here so if someone else was searching google for some options they might come across my article.

I arranged for lessons with Francisco Romero of the Cancun Spanish Language Institute.

http://www.studyspanish-mexico.com/

We had a great experience with Francisco.  We opted for an immersion type experience, with Francisco speaking almost no english during our lessons, but unlike some of the other instructors we have had, he was clearly 100% fluent in english, and could help explain some of the nuances in english. 

I would really recommend him to anyone else considering taking language lessons while in Cancun.

HP MediaSmart Certificate Issues

I am in the process of testing out a Windows Home Server (WHS) for possible use in backing up multiple machines.

Today I ran into a problem.  I noticed that when logging in remotely (using mydomain.homeserver.com) it was sending me to an http page and not an https page.

Asking me for my username/password that will allow anyone to access my machine over https is not acceptable.  I tried manually changing the url to https, but I got a certificate error.

I took a look at the certificate error and it appeared the certificate was for the URL https://MYDOMAIN  which is the name of the server, but not the full domain name.

I am not fully sure which change I made fixed the problem, but I went into Settings-> Remote Access and changed the “Web Site Home Page” from the HP page to the “Windows Home Server Home Page” because my friend had it setup this way and he had a button that took him to an HTTPS page to login, but I don’t think that solved the problem.  I then clicked on “Change” on the “Domain Name” section and just re-confirmed all the same settings.  At this point I think it grabs a new certificate from homeserver.com and it made it start working.

Now if I could only figure out why my one laptop is not backing up….

 

Extending Microsoft Data Access Blocks (early version)

Microsoft has released several versions of their Data Access Blocks, but they started mixing all their blocks together at some point, so if you wanted to use the DAB, you had to also use the Configuration blocks, and you had to use the Encryption blocks, and those needed the logging blocks etc.

So in many of my projects I have kept with one of the earlier versions.

But, there was a problem.  Basically in order to pass parameters, the easiest way to do it was in an ordinal position way, such as:

Public Shared Sub Whatever(SomeParamsHere)
    Dim storedParams() As SqlParameter
    storedParams = SqlHelperParameterCache.GetSpParameterSet(ConnectionString, "Whatever")

    storedParams(0).Value = 1
    storedParams(1).Value = 2
    storedParams(2).Value = 3
    storedParams(3).Value = "abc"

   SqlHelper.ExecuteNonQuery(ConnectionString, _
        CommandType.StoredProcedure, _
        "ItProjectInfo_General_Update", _
        storedParams)

End Sub

Obviously, this code is hard to read because we don’t know which parameters are getting which values w/o opening up the stored procedure and looking ourselves.

So I wrote some extra code to allow of working with SqlParameters in the form of Dictionary(Of String, SqlParameter).  Calling the same function would look like this:

Public Shared Sub Whatever(ByVal SomeParamsHere)
    Dim storedParams() As New Dictionary(Of String, SqlParameter)
    storedParams = SqlHelperParameterCache.GetSpParameterCollection(ConnectionString, "Whatever")

    storedParams.Item("@id").Value = 1
    storedParams.Item("@num").Value = 2
    storedParams.Item("@cat").Value = 3
    storedParams.Item("@name").Value = "abc"

    SqlHelper.ExecuteNonQuery(ConnectionString, _
         CommandType.StoredProcedure, _
         "ItProjectInfo_General_Update", _
         storedParams)

End Sub

This works for output parameters as well.

In order to make this work you need to edit the SqlHelper.vb code.

Inside the SqlHelperParameterCache class you need to add:

Public Overloads Shared Function GetSpParameterCollection(ByVal connectionString As String, ByVal spName As String) As System.Collections.Generic.Dictionary(Of String, SqlParameter)
    Dim parameters() As SqlParameter = GetSpParameterSet(connectionString, spName, False)
    Dim paramsCol As System.Collections.Generic.Dictionary(Of String, SqlParameter)
    paramsCol = SqlHelper.ParamArrayToDict(parameters)
    Return paramsCol
End Function

And inside SqlHelper class you need to add the following methods:

#Region " Dictionary Support Helpers "
Friend Shared Function ParamArrayToDict(ByVal params() As SqlParameter) As Dictionary(Of String, SqlParameter)
    Dim dict As New System.Collections.Generic.Dictionary(Of String, SqlParameter)(StringComparer.CurrentCultureIgnoreCase)
    For i As Integer = 0 To params.Length - 1
        dict.Add(params(i).ParameterName, params(i))
    Next
    Return dict
End Function

Friend Shared Function ParamDictToArray(ByVal dict As Dictionary(Of String, SqlParameter)) As SqlParameter()
    Dim params(dict.Count - 1) As SqlParameter
    Dim i As Integer
    For Each p As SqlParameter In dict.Values
        params(i) = p
        i += 1
    Next
    Return params
End Function
#End Region

Public Overloads Shared Function ExecuteDataset(ByVal connectionString As String, _
                                           ByVal commandType As CommandType, _
                                           ByVal commandText As String, _
                                           ByVal commandParameters As Dictionary(Of String, SqlParameter)) As DataSet ' Execute Dataset with generic dictionary support

    Dim parametersArray() As SqlParameter
    parametersArray = ParamDictToArray(commandParameters)
    Return ExecuteDataset(connectionString, commandType, commandText, parametersArray)
End Function


Public Overloads Shared Function ExecuteNonQuery(ByVal connectionString As String, _
                                              ByVal commandType As CommandType, _
                                              ByVal commandText As String, _
                                              ByVal commandParameters As Dictionary(Of String, SqlParameter)) As Integer
    Dim parametersArray() As SqlParameter
    parametersArray = ParamDictToArray(commandParameters)
    Return ExecuteNonQuery(connectionString, commandType, commandText, parametersArray)
End Function  ' ExecuteNonQuery with generic dictionary support


Public Overloads Shared Function ExecuteScalar(ByVal connectionString As String, _
                                              ByVal commandType As CommandType, _
                                              ByVal commandText As String, _
                                              ByVal commandParameters As Dictionary(Of String, SqlParameter)) As Object

    Dim parametersArray() As SqlParameter
    parametersArray = ParamDictToArray(commandParameters)
    Return ExecuteScalar(connectionString, commandType, commandText, parametersArray)

End Function ' ExecuteScalar with generic dictionary support

 

 

Using nant to build projects from the command line

NAnt is a tool that can help you build your .net applications. 

You can get really detailed with it, but what if you just want to set it up to quickly build projects/solutions or run automated builds.  This is especially useful if you are rebuilding 1 project that you are in the process of testing so you don’t have to wait for VS to figure out if any of the referenced projects need to be rebuilt.

Well, with a few quick steps you can have this.

After downloading NAnt you need to create a little batch file somewhere in your PATH (for example, c:windows).  Name the file nant.bat and put this in it:

@echo off
"C:appsnantnant-0.86-beta1binNAnt.exe" %*

You will obviously want to replace my path with your own path to your nant exe that you downloaded.

Then add an entry to your PATH system variable to the directory that contains devenv.com.  For me this path is:
C:Program FilesMicrosoft Visual Studio 8Common7ide

Then you just need to add a .build file to your project.  I name it the same as my project name but you can do whatever you want.

This build file should contain the following XML:

<?xml version="1.0"?>
<project name="ProjName" default="build" basedir=".">
  <target name="build">
    <exec failonerror="true" program="devenv.com" commandline="ProjName.vbproj /build Debug" />
  </target>
</project>

Rename ProjName as needed in this file as well.

Then all you need to do is navigate to the folder that contains the .build file from a command line and run:

nant

It will scan for the build file, and use devenv.com to build it.

You can also use this to build solutions, just change the .vbproj file to a .sln file.

Webservices: The request failed with HTTP status 400: Bad Request

We have a webservice that is called from an application under heavy use.

From time to time we are getting errors coming back from the webservice:

The request failed with HTTP status 400: Bad Request

The stack trace is not very helpful:

at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

So basically the webservice is just throwing back a 400 error to the webservice request.

I haven’t seen anyone online who has this type of issue.  I have seen several where they ALWAYS get this error, but none where it works most of the time and fails sometimes.

I am considering that it could be something in the network, like a proxy server or AV sniffer, but not sure.