在Visual Studio与EXE文件中DLL加载时间不同

Jer*_*und 2 c# exe .net-4.0 visual-studio-2010

我有一个在我的WPF程序中使用的通用实用程序DLL文件.我的程序做的第一件事是检查更新的dll文件并将其复制到执行目录 - 所有这些都没有引用来自dll的任何方法或属性.

当我从Visual Studio(v10)内部编译并运行程序时,一切都按预期工作.程序启动,检查dll文件,如果需要则复制,然后继续使用程序集.

如果我从Windows资源管理器运行已编译的.exe文件,它首先要做的是加载Util.dll程序集.这会锁定文件,不允许我更新它.

有没有人对Visual Studio与.exe文件中程序的选择有何不同?有关跟踪运行.exe文件时导致程序集加载的原因的任何想法?

这是程序启动的代码片段:

void AppLoad(object sender, StartupEventArgs e)
{

  //Used to see what assemblies are loaded.
  System.Text.StringBuilder sb = new System.Text.StringBuilder();
  foreach (var item in AppDomain.CurrentDomain.GetAssemblies())
  {
    sb.AppendLine(item.FullName.ToString());
  }
  System.IO.File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "test.txt", sb.ToString());


  //Check for the latest Util dll.
  if (!UpdateUtil())
  {
    //Shutdown.
    Application.Current.Shutdown();
    return;
  }

  //Start the main window.
  MainWindow m = new MainWindow();
  m.Show();
}

bool UpdateUtil()
{
  //Verify network path.
  if (!Directory.Exists(_componentPath))
  {
    MessageBox.Show("The program encountered an error.\r\rPlease contact your Program Administrator with the following information:\r\r" +
      "Program Name - Genesis Admin\r\r" +
      "Error Message - Network Component path not found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    return false;
  }
  //Verify file existance.
  string sourceFileName = _componentPath + "Util.dll";
  if (!File.Exists(sourceFileName))
  {
    MessageBox.Show("The program encountered an error.\r\rPlease contact your Program Administrator with the following information:\r\r" +
      "Program Name - Genesis Admin\r\r" +
      "Error Message - Network Util file not found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    return false;
  }

  string destFileName = AppDomain.CurrentDomain.BaseDirectory + "Util.dll";
  if (!File.Exists(destFileName) || File.GetLastWriteTime(sourceFileName) > File.GetLastWriteTime(destFileName))
    File.Copy(sourceFileName, destFileName, true);

  return true;
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

这通常是一件危险的事情,当需要为方法生成机器代码时,由即时编译器加载程序集.您可能不会指望的是内联代码,这是在发布版本中启用的重要优化.使用调试器运行时,该优化已关闭.

在您的代码段中,从"util.dll"加载哪种类型并不明显.但请确保重构您的代码,以便来自util.dll的所有类型都在远离UpdateUtil()调用的单独方法中.使用方法上的[MethodImpl(MethodImplOptions.NoInlining)]属性抑制内联.

到目前为止,最好的方法是使用一个小的bootstrapper .exe文件进行测试然后启动你的主.exe.但请记住,当您在用户的计算机上运行此代码时,无疑会再次碰到墙,您无法将DLL复制到没有UAC提升的c:\ program文件中.这实际上是一个安装程序任务,它不应该在您的代码中.