【问题标题】:c# Console Application Microsoft.Win32.TaskScheduler.dll FileNotFoundException on Deploymentc# Console Application Microsoft.Win32.TaskScheduler.dll FileNotFoundException on Deployment
【发布时间】:2016-07-21 20:36:55
【问题描述】:

我有一个应用程序,由于其性质,需要在工作时间之后运行,以免中断用户的工作流程。我已经下载并添加了对Microsoft.Win32.TaskScheduler.dll 的引用,这是根据另一个关于安排任务在当天晚些时候运行的最佳方式的问题的建议。

在调试中,程序按预期工作,但是在部署时,我收到以下错误:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Win32.TaskScheduler, Version=2.5.16.0, Culture=neutral, PublicKeyToken=0d013ddd5178a2ae' or one of its dependencies.

这让我相信 dll 在构建时没有正确添加到可执行文件中。

我为解决此问题所采取的步骤:

  1. 在解决方案资源管理器中,确保 Microsoft.Win32.TaskScheduler Copy Local 属性为 True
  2. 项目属性、发布、应用程序文件 - Microsoft.Win32.TaskScheduler.dll 包含在发布中、需要下载、包含哈希
  3. 移除依赖并重新添加
  4. 遵循this answer 中的建议

在这一点上,所有人都失败了。我可以确认 .dll 应该在 /bin/debug 文件夹中。此外,我以同样的方式手动添加了System.Management.Automation,它似乎按预期运行。

如果有人有任何其他建议,我们将不胜感激。

【问题讨论】:

  • 您是否在部署中包含了 TaskScheduler dll? IOW,不仅在您的 bin 文件夹中,还包括 .exe 运行的位置?
  • 将TaskScheduler.dll与已部署的程序放在同一目录并运行时,程序正确启动。但是,由于此部署的设置方式,我仅限于单个文件。编辑:我应该将 dll 添加为资源并在运行时将文件写入文件目录还是有替代/更好的解决方案?
  • 那么听起来部署设置需要更改;如果 DLL 需要在那里才能运行应用程序,则需要对其进行部署。
  • 如果您受限于单个文件(无论出于何种原因),this question 的答案可能会对您有所帮助。 System.Management.Automation 可能已经存在于全局程序集缓存中,因为它是 PowerShell 的一部分

标签: c# dll include scheduled-tasks


【解决方案1】:

我曾尝试使用derpirscher 的解决方案,但我最终使用的解决方案是将dll 部署到程序的运行目录。这不是最优雅的解决方案,但它满足了“单文件部署”的要求。然而,应该注意的是,在部署到的所有系统上,用户帐户都是管理员。如果运行程序的用户不是管理员,则此解决方案可能不起作用,具体取决于运行可执行文件的位置(例如,另一个用户的帐户文件夹)。

class Program
{
    //Deploys the DLL to the location of the executable, as suggested by B. Clay Shannon
    //The Program() method runs before Main() and allows for regisration or placement
    //of files before the program "starts". Placing this line in Main()
    //causes a FileNotFound exception when it tries to register the assembly.
    static Program()
    {
        //The dll has been added as a resource, build action "Content".
        //Note the underscores in "Microsoft_Win32_TaskScheduler"
        //Adding the dll to the resource manager replaces '.' with '_' in the resource name
        File.WriteAllBytes(string.Format("{0}{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\Microsoft.Win32.TaskScheduler.dll"), FindResourceByName("Microsoft_Win32_TaskScheduler"));
    }

    static void Main(string[] args)
    {
        ...
    }

    /// <summary>
    ///   Returns a byte array of the object searched for
    /// </summary>
    /// <param name="objectName">Name of the resource object</param>
    /// <returns>Byte array of the specified resource object</returns>
    private static byte[] FindResourceByName(string objectName)
    {
        object obj = Properties.Resources.ResourceManager.GetObject(objectName);
        return ((byte[])(obj));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 2018-07-24
    • 2010-10-16
    相关资源
    最近更新 更多