如何在 C# 中测试文件是否为 .Net 程序集
How to test whether a file is a .Net assembly in C#
我写了下面的代码:
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,那就更好了。
您可以尝试使用 GetAssemblyName()
method to attempt to resolve if it was an actual assembly similar to the technique mentioned in this MSDN documentation :
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)
- 它不加载程序集但 open/closes 文件来读取程序集清单(如果不正确则抛出 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# 示例的略微修改版本 here。
如果文件不是 .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();
我写了下面的代码:
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,那就更好了。
您可以尝试使用 GetAssemblyName()
method to attempt to resolve if it was an actual assembly similar to the technique mentioned in this MSDN documentation :
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)
- 它不加载程序集但 open/closes 文件来读取程序集清单(如果不正确则抛出 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# 示例的略微修改版本 here。
如果文件不是 .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();