Q:

C# Linq Registry values to DataTable

I am trying to enumerate the registry to fetch a list of installed applications and return them via Linq to a DataTable in C#.
I have tried various things including sanitizing it as XML (which worked), however it seemed rather inefficient as ultimately, i require this as DataTable object.
Here is where i am at currently:
            //Warning 
   public static DataRow DataRowInstalledApplication (this RegistryKey rgkey, string keyName)
        {
            RegistryKey key = rgkey.OpenSubKey(keyName, false);
            try
            {
                //Application Name is mandetory for a given key.
                if (key == null|| key.RegToString("DisplayName", false) == null )return null;
                //Build a sanitised data row
                var rowBuilder = new DataTable().NewRow();
                rowBuilder["DisplayName"] = key.RegToString("DisplayName");
                rowBuilder["UninstallString"] = key.RegToString("UninstallString");
                rowBuilder["InstallLocation"] = key.RegToString("InstallLocation");
                rowBuilder["Publisher"] = key.RegToString("Publisher");
                rowBuilder["DisplayIcon"] = key.RegToString("DisplayIcon");

                return rowBuilder;
            }
            finally
            {
                if (key != null) key.Close();
            }

        }

Here is the method that contains the Linq:
        public DataTable GetRegistryApplicationDataTable(RegistryKey registryKey, string tableName)
    {

        if (registryKey != null)
        {
            try
            {
                //change to throw non critical error
                var installedListXml = new DataTable(tableName, from name in registryKey.GetSubKeyNames()
                                                                let app = registryKey.DataRowInstalledApplication(name)

                                                                select app);
                return installedListXml;
            }
            catch
            {
                return new DataTable(tableName);
            }
            finally
            {
                registryKey.Close();
            }

        }
        return null;
    }

The main problem i have is that i do not really understand Linq very well. Mainly how individual values are used during the iteration to call other things similar to
foreach (string value in collection)
{
    Somefunction(value);
}

, in the case of the registry values i am trying to retrieve, i do not understand how to make a Linq query pass each key name to function, which will generate a row and the Linq Query return as a data table.
I would be grateful of any pointers!  thanks
ps i call the above with
private static readonly RegistryKey HKLMUninstallKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");

GetRegistryApplicationDataTable(HKLMUninstallKey, "Computer")

and expect back a data table called computer.

A:

Your first problem is your linq statement. You are trying to pass an IEnumerable into a constructor that is expecting either a (string) or a (string, string). If you modify your logic to this:
var query = from name in registryKey.GetSubKeyNames()
let app = registryKey.DataRowInstalledApplication(name)
select app;

foreach(var result in query)
{
    var installedListXml = new DataTable(tableName, result);
}

That would work IF result was actually a string, but it's a DataRow, which is not a valid parameter for a DataTable constructor. Instead, there is an extension method you can call on the resulting query to copy to a data table, like so:
var query = from name in registryKey.GetSubKeyNames()
let app = registryKey.DataRowInstalledApplication(name)
select app;

var installedListXml = query.CopyToDataTable();

When you write a LINQ query statement, it is not executed until you try to enumerate over the results. CopyToDataTable does this, so if you were to step through your code you will notice that your function DataRowInstalledApplication will not be called until you call CopyToDataTable and not when you first assign query. The result you receive is an Enumerator that you can treat just like any other, whether that's using in a foreach loop or calling ToList or so forth. Inside the linq query itself, you are actually iterating over other values, in this case GetSubKeyNames. It would be functionally equivalent if you were to do this instead:
var dataRows = new List<DataRow>();
foreach(var name in registryKey.GetSubKeyNames())
{
    dataRows.Add(registryKey.DataRowInstalledApplication(name));
}

return dataRows.CopyToDataTable();

