Windows 7 Start menu search not working

Searching from the start menu resulted in no results

Searching from the start menu suddenly stopped working on one of my machines recently. Only when it stopped working did I realise how much I had started to rely upon it to find programs, configuration wizards and such like.

Trawling the forums unearthed many suggestions. Often the suggestions were to solve similar symptoms but did not resolve the issue I was experiencing. Starting to search would show ghosts of the category headings but not results.

You can see this in the screen shot below.

nosearch

 

The solution that worked for me is the last one I give here but the journey can help find all the touch points for search.

Check Customize Start Menu options

If it is merely the programs are not showing up then use the customise start menu, right click start menu>properties>customise. Ensure the search program files menu option is selected as shown;

StartMenuSearchOptions

From the control panel it is possible to manage the search index

Use the windows search trouble shooter

There are many trouble shooters found here;

Control Panel\All Control Panel Items\Troubleshooting\All Categories

Amongst them is a search and indexing trouble shooter. Give it a try, it reported no problems for me even though obviously something was up.

searchtroubleshooter

 

Check search is enabled as a feature

From Control Panel\Programs\Programs and Features go to windows features. This allows search as a feature to be turned on or off. Try turning off, reboot then turn on, reboot.

searchfeatures

 

Rebuild the index

By going to the search options you can click the advanced button and then rebuild the index.

indexingoptions

Finally fix the registry

In my case it was the following registry fix that worked.

Navigate to the following registry key;

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{EF87B4CB-F2CE-4785-8658-4CA6C63E38C6}\TopViews\{00000000-0000-0000-0000-000000000000}

Find the value GroupBy and if it is System.Null,  change it to value System.StartMenu.Group.

Killing explorer.exe process then re-launching it or rebooting will now allow the start search to work!

Sagepay Access protocol for .NET (VB.NET) using LINQ

Sagepay are a card payment provider. There is a new Sagepay API to manage the actions that are normally accessed through the account management web portal “MySagePay”. At time of writing it is in restricted Beta. As it is not open I feel unable to disclose everything about how it works, but if you are using the beta service with .NET then parts of my wrapper may be useful to you.

To get in on the Beta, go into the Sagepay website Access forum and PM Joe in support who will send you the API documents. If you want my .NET wrapper for Access then I don’t mind sharing but would need to confirm with you that you have been given the Beta documentation first.

LINQ to XML seemed like the best way forward so here goes;

Prepare the XML

I’ve left out the command name, you can replace it if you have the API documentation as you will know what it is. For each call in the API you start with the same XML fragment then append the relevant parameters to it.

Public Shared Function lockUserXMLRequest( _
 ByVal VendorID As String, ByVal UserName As String, ByVal Password As String, _
                      ByVal lockusername As String) As XElement
    If lockusername.Length > 20 Then Throw New ArgumentException("username must be 20 characters maximum", _
         "lockusername", Nothing)
    Dim SagePayRequestXML As XElement = New Credentials("[commandname]", VendorID, UserName, Password)
    SagePayRequestXML.Element("user").AddAfterSelf(<username><%= lockusername %></username>)
    Return HashRequestxml(SagePayRequestXML)
End Function
 
The credentials are passed in for each request as an xElement;
 
Public Class Credentials
    Inherits XElement
 
    Public Sub New(ByVal Command As String, ByVal VendorID As String, _
                   ByVal UserName As String, ByVal Password As String)
        MyBase.New("vspaccess")
        If UserName.Length > 20 Then
            Throw New ArgumentException("UserName maximum of 20 character", "UserName", Nothing)
        End If
        If VendorID.Length > 16 Then
            Throw New ArgumentException("VendorID maximum of 16 character", "VendorID", Nothing)
        End If
        If Password.Length > 32 Then
            Throw New ArgumentException("Password maximum of 32 character", "Password", Nothing)
        End If
        Me.Add(<command><%= Command %></command>)
        Me.Add(<vendor><%= VendorID %></vendor>)
        Me.Add(<user><%= UserName %></user>)
        Me.Add(<password><%= Password %></password>)
    End Sub
End Class

Hash the request

Once you have the XML it is hashed with your vendor password, the password must be removed before the XML is submitted to Sagepay;

Private Shared Function HashRequestxml(ByVal RequestElement As XElement) As XElement
    ''Is there a better way to convert xElement() to string?
    Dim sb As New StringBuilder
    For Each currentElement In RequestElement.Elements
        sb.Append(currentElement.ToString)
    Next
 
    ' Get the "inner xml" of the element
    Dim oReader = RequestElement.CreateReader()
    oReader.MoveToContent()
    Dim asstring = oReader.ReadInnerXml()
 
    'Hash the request and password element together and use the result
    ' as the signature
    Dim signature As XElement = _
            <signature><%= getMd5Hash(asstring) %></signature>
    'Now remove the password, not required now hash generated
    RequestElement.Element("password").Remove()
    RequestElement.Add(signature)
    Return RequestElement
End Function

Note: A post in the Sagepay forum indicates that the final Access may be significantly different to the current one in use. See: Our improved Reporting & Admin API is coming...

LINQ SQL innerxml equivalent

A note to myself, if you have an xElement and want to get just the inner xml then this is the way to do it:

' Get the "inner xml" of the element
Dim oReader = RequestElement.CreateReader()
oReader.MoveToContent()
Dim asstring = oReader.ReadInnerXml()