c# 控制台应用程序 Microsoft.Win32.TaskScheduler.dll FileNotFoundException on Deployment
c# Console Application Microsoft.Win32.TaskScheduler.dll FileNotFoundException on Deployment
我有一个应用程序,由于其性质,需要在下班后运行,以免打断用户的工作流程。根据另一个问题的建议,我已经下载并添加了对 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 在构建时没有正确添加到可执行文件中。
我已采取的解决此问题的步骤:
- 在解决方案资源管理器中,确保 Microsoft.Win32.TaskScheduler 复制本地 属性 是 True
- 项目属性,发布,应用程序文件 - Microsoft.Win32.TaskScheduler.dll 包含在发布中,需要下载,包含哈希
- 移除依赖并重新添加
- 遵循了this answer
中的建议
在这一点上,所有人都失败了。我可以确认 .dll 位于 /bin/debug 文件夹中。此外,我以相同的方式手动添加了 System.Management.Automation
,它似乎按预期运行。
如果有人有任何其他建议,我们将不胜感激。
我曾尝试使用derpirscher的解决方案,但我最终使用的解决方案是将dll部署到程序的运行ning目录。这不是最优雅的解决方案,但它满足 "single file deployment" 要求。但是,应该注意的是,在部署到的所有系统上,用户帐户都是管理员。如果程序 运行s 所在的用户不是管理员,则此解决方案可能不起作用,具体取决于可执行文件来自 运行 的位置(例如,另一个用户的帐户文件夹)。
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));
}
}
我有一个应用程序,由于其性质,需要在下班后运行,以免打断用户的工作流程。根据另一个问题的建议,我已经下载并添加了对 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 在构建时没有正确添加到可执行文件中。
我已采取的解决此问题的步骤:
- 在解决方案资源管理器中,确保 Microsoft.Win32.TaskScheduler 复制本地 属性 是 True
- 项目属性,发布,应用程序文件 - Microsoft.Win32.TaskScheduler.dll 包含在发布中,需要下载,包含哈希
- 移除依赖并重新添加
- 遵循了this answer 中的建议
在这一点上,所有人都失败了。我可以确认 .dll 位于 /bin/debug 文件夹中。此外,我以相同的方式手动添加了 System.Management.Automation
,它似乎按预期运行。
如果有人有任何其他建议,我们将不胜感激。
我曾尝试使用derpirscher的解决方案,但我最终使用的解决方案是将dll部署到程序的运行ning目录。这不是最优雅的解决方案,但它满足 "single file deployment" 要求。但是,应该注意的是,在部署到的所有系统上,用户帐户都是管理员。如果程序 运行s 所在的用户不是管理员,则此解决方案可能不起作用,具体取决于可执行文件来自 运行 的位置(例如,另一个用户的帐户文件夹)。
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));
}
}