c#控制台应用程序Microsoft.Win32.TaskScheduler.dll FileNotFoundException在部署时发生异常
我有一个应用程序,由于它的性质,需要在工作时间之后运行,以免中断用户的工作流程。根据另一个问题的建议,我已下载并添加了对的参考,该问题涉及安排任务在当天晚些时候运行的最佳方式 在调试过程中,程序按预期工作,但是在部署时,我遇到以下错误:c#控制台应用程序Microsoft.Win32.TaskScheduler.dll FileNotFoundException在部署时发生异常,c#,dll,include,scheduled-tasks,C#,Dll,Include,Scheduled Tasks,我有一个应用程序,由于它的性质,需要在工作时间之后运行,以免中断用户的工作流程。根据另一个问题的建议,我已下载并添加了对的参考,该问题涉及安排任务在当天晚些时候运行的最佳方式 在调试过程中,程序按预期工作,但是在部署时,我遇到以下错误: Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Win32.TaskScheduler, Version=2.5.1
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在构建时没有正确地添加到可执行文件中
我采取了以下步骤来解决此问题:
System.Management.Automation
,它的功能似乎与预期的一样
如果有人有任何其他建议,我们将不胜感激。我曾尝试使用的解决方案,但最终使用的解决方案是将dll部署到程序的运行目录。这不是最优雅的解决方案,但它满足了“单文件部署”的要求。但是,应该注意,在部署到的所有系统上,用户帐户都是管理员。如果运行程序的用户不是管理员,则此解决方案可能无法工作,具体取决于可执行文件的运行位置(例如,其他用户的帐户文件夹)
类程序
{
//按照B.Clay Shannon的建议,将DLL部署到可执行文件的位置
//Program()方法在Main()之前运行,并允许注册或放置
//在程序“启动”之前的文件数。将此行放在Main()中
//在尝试注册程序集时导致FileNotFound异常。
静态程序()
{
//dll已添加为资源,生成操作“内容”。
//请注意“Microsoft_Win32_TaskScheduler”中的下划线
//将dll添加到资源管理器会将资源名称中的“.”替换为“\u1”
File.writealBytes(string.Format(“{0}{1}”、Path.GetDirectoryName(Assembly.getExecutionGassembly().Location)、“\\Microsoft.Win32.TaskScheduler.dll”、FindResourceByName(“Microsoft_Win32_TaskScheduler”);
}
静态void Main(字符串[]参数)
{
...
}
///
///返回所搜索对象的字节数组
///
///资源对象的名称
///指定资源对象的字节数组
私有静态字节[]FindResourceByName(字符串objectName)
{
object obj=Properties.Resources.ResourceManager.GetObject(objectName);
返回((字节[])(obj));
}
}
部署中是否包含TaskScheduler dll?注意,不仅在bin文件夹中,而且在.exe运行的位置?将TaskScheduler.dll放置在与部署的程序相同的目录中并运行它时,程序将正确启动。但是,由于此部署的设置方式,我仅限于一个文件。编辑:我应该添加dll作为资源,并在运行时将文件写入文件目录,还是有替代/更好的解决方案?那么听起来部署设置需要更改;如果应用程序需要有DLL才能运行,则需要对其进行部署。如果您仅限于一个文件(无论出于何种原因),则此问题的答案可能会对您有所帮助。全局程序集缓存中可能已经存在System.Management.Automation,因为这是PowerShell的一部分
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));
}
}