【问题标题】:Getting the Last Modified Date of an assembly in the GAC在 GAC 中获取程序集的最后修改日期
【发布时间】:2010-12-30 07:02:28
【问题描述】:

我已经实现了许多帖子中提到的 fusion.dll 包装器,现在发现我需要确定是否需要更新的至少一个 dll 不是使用构建号和修订号。因此,我无法比较版本号,需要比较上次修改日期。

fusion.dll 或其包装器没有这样的方法,我认为这很公平,但我如何确定 dll 的“真实”路径,以便我可以发现它的最后修改日期。

到目前为止我的代码:

private DateTime getGACVersionLastModified(string DLLName)
{
  FileInfo fi = new FileInfo(DLLName);
  string dllName = fi.Name.Replace(fi.Extension, "");

  DateTime versionDT = new DateTime(1960,01,01);

  IAssemblyEnum ae = AssemblyCache.CreateGACEnum();
  IAssemblyName an;
  AssemblyName name;
  while (AssemblyCache.GetNextAssembly(ae, out an) == 0)
  {
    try
    {
      name = GetAssemblyName(an);

      if (string.Compare(name.Name, dllName, true) == 0)
      {
        FileInfo dllfi = new FileInfo(string.Format("{0}.dll", name.Name));
        if (DateTime.Compare(dllfi.LastWriteTime, versionDT) >= 0)
          versionDT = dllfi.LastWriteTime;
      }
    }
    catch (Exception ex)
    {
      logger.FatalException("Unable to get version number: ", ex);
    }
  }
  return versionDT;
}

【问题讨论】:

  • 我已经很久没有使用 Fusion API 了。但是您是否尝试过调用 IAssemblyCache.QueryAssemblyInfo ?它应该返回一个文件路径。

标签: c# reflection assemblies gac


【解决方案1】:

从您问题中的问题描述中,我可以看到您确实要完成 2 个主要任务:

1) 确定是否可以从 GAC 加载给定的程序集名称。
2) 返回给定程序集的文件修改日期。

我相信这两点可以通过更简单的方式完成,而无需使用unmanaged fusion API。执行此任务的更简单方法可能如下:

static void Main(string[] args)
{
  // Run the method with a few test values
  GetAssemblyDetail("System.Data"); // This should be in the GAC
  GetAssemblyDetail("YourAssemblyName");  // This might be in the GAC
  GetAssemblyDetail("ImaginaryAssembly"); // This just plain doesn't exist
}

private static DateTime? GetAssemblyDetail(string assemblyName)
{
  Assembly a;
  a = Assembly.LoadWithPartialName(assemblyName);
  if (a != null)
  {
    Console.WriteLine("'{0}' is in GAC? {1}", assemblyName, a.GlobalAssemblyCache);
    FileInfo fi = new FileInfo(a.Location);
    Console.WriteLine("'{0}' Modified: {1}", assemblyName, fi.LastWriteTime);
    return fi.LastWriteTime;
  }
  else
  {
    Console.WriteLine("Assembly '{0}' not found", assemblyName);
    return null;
  }
}

结果输出示例:

'System.Data' 在 GAC 中?真的
'System.Data' 修改时间:2010 年 10 月 1 日上午 9:32:27
'YourAssemblyName' 在 GAC 中?假的
'YourAssemblyName' 修改时间:12/30/2010 4:25:08 AM
未找到程序集“ImaginaryAssembly”

【讨论】:

  • GAC COM API 未记录在案。见msdn.microsoft.com/en-us/library/ms404523.aspx
  • 感谢 Mattias 指出 fusion API 的文档。我没有意识到这一点,并更新了我的答案摘要以反映它实际上已记录在案。
  • 大卫,我想尝试比较多个版本是一个更复杂的问题。如果您修改上面的代码使用 Assembly.Load(AssemblyName) 而不是 LoadWithPartialName 并使用程序集的强名称,您可能能够比较版本(我没有测试过)。这假设您知道多个版本的强名称。否则,LoadWithPartialName 根据 MSDN 加载“最高版本号”...在您的情况下,考虑到您的程序集不使用构建和修订号,我不知道这可能会做什么。
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多