如何在 C# 中测试文件是否为 .Net 程序集

本文关键字:是否 Net 程序集 文件 测试 | 更新日期: 2024-11-07 21:42:19

我写了以下代码:

public DataTable GetDotNetAssemblies(string baseDirectory)
{
    DataTable MethodResult = null;
    try
    {
        if (Directory.Exists(baseDirectory))
        {
            List<string> FilePaths = NetworkConnection.GetAllFilesUnderDirectory(baseDirectory);
            DataTable dt = new DataTable();
            dt.Columns.Add("Directory");
            dt.Columns.Add("Filename");
            dt.Columns.Add("Date modified");
            dt.Columns.Add("Bytes");
            dt.Columns.Add("User modified");
            foreach (string FilePath in FilePaths)
            {
                DataRow dr = dt.NewRow();
                FileInfo f = new FileInfo(FilePath);
                List<string> AllowedExtensions = new List<string>();
                AllowedExtensions.Add(".exe");
                AllowedExtensions.Add(".dll");
                if (AllowedExtensions.Contains(f.Extension.ToLower()))
                {
                    dr["Directory"] = f.Directory;
                    dr["Filename"] = f.Name;
                    dr["Date modified"] = f.LastWriteTime;
                    dr["Bytes"] = f.Length.ToString();
                    string UserModified = "";
                    try
                    {
                        UserModified = f.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
                    }
                    catch
                    {
                        UserModified = "Unknown";
                    }
                    dr["User modified"] = UserModified;
                    dt.Rows.Add(dr);
                }
            }
            dt.AcceptChanges();
            MethodResult = dt;
        }
        else
        {
            MessageBox.Show("Unable to connect to directory:'n" + baseDirectory);
        }
    }
    catch (Exception ex)
    {
        ex.HandleException();
    }
    return MethodResult;
}

我已经按文件扩展名过滤,您可以通过以下行看到:

if (AllowedExtensions.Contains(f.Extension.ToLower()))

我需要通过检查程序集文件是否是 .Net 程序集来进一步过滤它们。

我可以对文件执行测试吗?

此外,如果可以发现程序集中使用了哪个版本的 .Net CLR,那就更好了。

如何在 C# 中测试文件是否为 .Net 程序集

您可以尝试使用 GetAssemblyName() 方法尝试解析它是否是类似于此 MSDN 文档中提到的技术的实际程序集:

public string bool IsValidAssembly(string path)
{
    try
    {
          // Attempt to resolve the assembly
          var assembly = GetAssemblyName(path);
          // Nothing blew up, so it's an assembly
          return true;
    }
    catch(Exception ex)
    {
          // Something went wrong, it is not an assembly (specifically a 
          // BadImageFormatException will be thrown if it could be found
          // but it was NOT a valid assembly
          return false;
    }   
}

因此,您可以考虑在代码中使用以下方法:

// Check that it is a valid extension and a valid assembly
if (AllowedExtensions.Contains(f.Extension.ToLower()) && IsValidAssembly(FilePath))
{
     // At this point it should be valid, so continue
}
我相信

您可能需要使用 AssemblyName.GetAssemblyName(path) - 它不会加载程序集,但打开/关闭文件以读取程序集清单(如果不确定,则抛出System.BadImageFormatException

https://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getassemblyname.aspx

修改后的代码

修改为筛选 .Net 程序集:

    public DataTable GetDotNetAssemblies(string baseDirectory)
    {
        DataTable MethodResult = null;
        try
        {
            if (Directory.Exists(baseDirectory))
            {
                List<string> FilePaths = NetworkConnection.GetAllFilesUnderDirectory(baseDirectory);
                DataTable dt = new DataTable();
                dt.Columns.Add("Directory");
                dt.Columns.Add("Filename");
                dt.Columns.Add("Date modified");
                dt.Columns.Add("Bytes");
                dt.Columns.Add("User modified");
                dt.Columns.Add(".Net CLR version");
                foreach (string FilePath in FilePaths)
                {
                    DataRow dr = dt.NewRow();
                    FileInfo f = new FileInfo(FilePath);
                    List<string> AllowedExtensions = new List<string>();
                    AllowedExtensions.Add(".exe");
                    AllowedExtensions.Add(".dll");
                    bool IsDotNetAssembly = false;
                    try
                    {
                        AssemblyName a = AssemblyName.GetAssemblyName(FilePath);
                        IsDotNetAssembly = true;
                    } catch {}
                    if (AllowedExtensions.Contains(f.Extension.ToLower()) && IsDotNetAssembly)
                    {
                        dr["Directory"] = f.Directory;
                        dr["Filename"] = f.Name;
                        dr["Date modified"] = f.LastWriteTime;
                        dr["Bytes"] = f.Length.ToString();
                        try
                        {
                            Assembly a = Assembly.GetAssembly(AssemblyName.GetAssemblyName(FilePath).GetType());
                            dr[".Net CLR version"] = a.ImageRuntimeVersion.ToString();
                        }
                        catch //(Exception ex2)
                        {
                            //ex2.HandleException();
                        }
                        string UserModified = "";
                        try
                        {
                            UserModified = f.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
                        }
                        catch
                        {
                            UserModified = "Unknown";
                        }
                        dr["User modified"] = UserModified;
                        dt.Rows.Add(dr);
                    }
                }
                dt.AcceptChanges();
                MethodResult = dt;
            }
            else
            {
                MessageBox.Show("Unable to connect to directory:'n" + baseDirectory);
            }
        }
        catch //(Exception ex)
        {
            //ex.HandleException();
        }
        return MethodResult;
    }

测试 1

此处找到的 C# 示例的略微修改版本。

如果文件不是 .Net 程序集,则会引发异常。

bool IsDotNetAssembly = false;
try
{
    AssemblyName a = AssemblyName.GetAssemblyName(FilePath);
    IsDotNetAssembly = true;
} catch {}

测试 2

告诉您是 CLR 的版本,即 .NET 编译器版本:

Assembly a = Assembly.GetAssembly(AssemblyName.GetAssemblyName(FilePath).GetType());
dr[".Net CLR version"] = a.ImageRuntimeVersion.ToString();