Search code examples
c#.netfiledatatablefileinfo

How to test whether a file is a .Net assembly in C#


I have written the following code:

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;
}

I am already filtering by file extension, which you can see by the line:

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

What I need is to filter the assembly files further, by checking whether they are .Net assemblies or not.

Is there a test I can perform on a file?

Additionally, if it's possible to discover which version of .Net CLR is used in the assembly then that would be better still.


Solution

  • Modified code

    Modified to filter .Net assemblies:

        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;
        }
    

    Test 1

    A slightly modified version of the C# example found here.

    An exception will be thrown if the file is not a .Net assembly.

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

    Test 2

    Tells your the version of CLR, which is the .NET compiler version:

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