【问题标题】:How to test whether a file is a .Net assembly in C#如何在 C# 中测试文件是否为 .Net 程序集
【发布时间】:2016-04-22 15:33:46
【问题描述】:

我写了以下代码:

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 file datatable fileinfo


    【解决方案1】:

    如果它是类似于the technique mentioned in this MSDN documentation 的实际程序集,您可以尝试使用GetAssemblyName() 方法来尝试解析:

    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
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        修改后的代码

        修改为过滤 .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

        here 找到了 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();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-12
          • 2010-09-26
          • 2010-12-21
          • 1970-01-01
          • 2011-04-12
          • 2014-06-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多