Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Linq注册表值到数据表_C#_.net_Linq_Datatable - Fatal编程技术网

C#Linq注册表值到数据表

C#Linq注册表值到数据表,c#,.net,linq,datatable,C#,.net,Linq,Datatable,我试图枚举注册表以获取已安装应用程序的列表,并通过Linq将它们返回到C#中的数据表中 我尝试过各种方法,包括将其作为XML进行清理(这是有效的),但是它似乎效率很低,因为最终,我需要将其作为DataTable对象 以下是我目前的情况: //Warning public static DataRow DataRowInstalledApplication (this RegistryKey rgkey, string keyName) {

我试图枚举注册表以获取已安装应用程序的列表,并通过Linq将它们返回到C#中的数据表中

我尝试过各种方法,包括将其作为XML进行清理(这是有效的),但是它似乎效率很低,因为最终,我需要将其作为DataTable对象

以下是我目前的情况:

            //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();
            }

        }
以下是包含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;
    }
我的主要问题是,我对Linq不是很了解。主要是如何在迭代过程中使用单个值来调用与

foreach (string value in collection)
{
    Somefunction(value);
}
,对于我试图检索的注册表值,我不知道如何使Linq查询将每个键名传递给函数,函数将生成一行,Linq查询将作为数据表返回

如果有人给我指点,我将不胜感激!谢谢

ps我把上面的问题称为

private static readonly RegistryKey HKLMUninstallKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");

GetRegistryApplicationDataTable(HKLMUninstallKey, "Computer")

然后返回一个名为computer的数据表。

您的第一个问题是linq语句。您正试图将一个
IEnumerable
传递给一个构造函数,该构造函数需要一个(
string
)或(
string
string
)。如果将逻辑修改为:

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);
}
如果结果实际上是一个字符串,但它是一个
DataRow
,这对于
DataTable
构造函数来说不是一个有效的参数,那么这就行了。相反,您可以调用一个扩展方法来将结果查询复制到数据表,如下所示:

var query = from name in registryKey.GetSubKeyNames()
let app = registryKey.DataRowInstalledApplication(name)
select app;

var installedListXml = query.CopyToDataTable();
当您编写LINQ查询语句时,在尝试枚举结果之前,不会执行该语句
CopyToDataTable
会执行此操作,因此,如果您要单步执行代码,您会注意到,在调用
CopyToDataTable
之前,不会调用函数
DataRowInstalledApplication
,而在首次分配
查询时也不会调用。您收到的结果是一个
枚举数
,您可以像对待任何其他枚举数一样对待它,无论它是在
foreach
循环中使用还是调用
ToList
等等。在linq查询本身内部,您实际上是在迭代其他值,在本例中是
GetSubKeyNames
。如果您改为这样做,它在功能上是等效的:

var dataRows = new List<DataRow>();
foreach(var name in registryKey.GetSubKeyNames())
{
    dataRows.Add(registryKey.DataRowInstalledApplication(name));
}

return dataRows.CopyToDataTable();
var dataRows=newlist();
foreach(registryKey.GetSubKeyNames()中的变量名)
{
Add(registryKey.DataRowInstalledApplication(名称));
}
返回dataRows.CopyToDataTable();

感谢您的示例和解释,非常有帮助!