C# 无法注册COM对象以在计划任务中使用
我正在尝试创建一组C#类,可以安排在将来运行。目的是通过我的代码的其他部分以编程方式安排这些 这是我试图通过COM调用的当前类C# 无法注册COM对象以在计划任务中使用,c#,windows,com,windows-10,registry,C#,Windows,Com,Windows 10,Registry,我正在尝试创建一组C#类,可以安排在将来运行。目的是通过我的代码的其他部分以编程方式安排这些 这是我试图通过COM调用的当前类 using System; using System.Linq; using System.Runtime.InteropServices; using Microsoft.Win32.TaskScheduler; namespace SchedulableTasks { [Guid("F5CAE94C-BCC7-4304-BEFB-FE1E5D56309A"
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32.TaskScheduler;
namespace SchedulableTasks
{
[Guid("F5CAE94C-BCC7-4304-BEFB-FE1E5D56309A")]
public class TaskRegistry : ITaskHandler
{
private ITaskHandler _taskHandler;
public void Start(object pHandlerServices, string data)
{
var arguments = data.Split('|');
var taskTypeName = arguments.FirstOrDefault();
var taskArguments = arguments.Skip(1).FirstOrDefault();
var taskType = Type.GetType(taskTypeName);
_taskHandler = (ITaskHandler) Activator.CreateInstance(taskType);
_taskHandler.Start(pHandlerServices, taskArguments);
}
public void Stop(out int pRetCode)
{
var retCode = 1;
_taskHandler?.Stop(out retCode);
pRetCode = retCode;
}
public void Pause()
{
_taskHandler.Pause();
}
public void Resume()
{
_taskHandler.Resume();
}
}
}
下面是我如何安排任务的
using System;
using Microsoft.Win32.TaskScheduler;
using Newtonsoft.Json;
using Action = Microsoft.Win32.TaskScheduler.Action;
namespace MyProject.Service
{
public static class SchedulingService
{
public enum ScheduledTask
{
BillingQuery
}
private static readonly Guid RegistryGUI = new Guid("F5CAE94C-BCC7-4304-BEFB-FE1E5D56309A");
public static void ScheduleAction(string name, string description, Trigger trigger, Action action)
{
using (var taskService = new TaskService())
{
var task = taskService.NewTask();
task.RegistrationInfo.Description = description;
task.Triggers.Add(trigger);
task.Actions.Add(action);
taskService.RootFolder.RegisterTaskDefinition(name, task);
}
}
public static Action CreateCSharpAction(ScheduledTask task, object data)
{
var taskData = $"{task.ToString()}|{JsonConvert.SerializeObject(data)}";
return new ComHandlerAction(RegistryGUI, taskData);
}
}
}
Microsoft.Win32.TaskScheduler
是的2.7.2版
我可以毫无问题地创建计划任务,但是当我尝试运行它时,我得到一个未注册的类(0x80040154)
在my.csproj中,我将程序集注册为COM对象。
对于PlatformTarget
属性,我使用相应的regasm.exe
尝试了所有AnyCPU
、x86
和x64
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RegisterForComInterop>true</RegisterForComInterop>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
据我所知,它是正确注册的。
Procmon.exe似乎也报告了同样的情况。我担心的是\TreatAs
、\InprocHandler
和\InprocServer32\InprocServer32
我想我看到了你的问题: 尝试瞄准x86。请参阅此答案以了解详细说明: 编辑: 我无法重新编程,我添加了一些内容:
[ComVisible(true)]
Nope,即使将
AnyCPU
更改为x86
我仍然会收到相同的错误。我还希望将其注册为x64 DLL,因为我的其余代码是64位的。我如何重新编程?您错过了任务服务的定义。我是否只需要创建一个带有TaskRegistry
的类库(Full.Net),然后引用并实例化它?TaskService
来自。是的,我在他们自己的项目中有两个文件。我有TaskRegistry
引用的单个任务定义,但是从ITaskHandler
继承的任何东西都可以工作。我不在乎它是否在调用TaskRegistry.Start
后立即崩溃。这两个项目都是根据4.6.2编写的。我参考了David Halls图书馆,目标是4.6.1,你否决了我吗?请提供一个?我仍然有一些问题与类没有注册。明天我将尝试提出更深入的MCVE。不,不是我。我不明白TaskRegistration类想做什么。它应该执行任务,而不是试图一意孤行。也许这是一个有意的额外间接操作,但诊断是任何“BillingQuery”都没有正确注册。尽管这不应引发此异常,因为它已由Activator.CreateInstance()创建。嗯,只要执行任务。@HansPassant的想法是允许我只注册一个类,但根据调用方将它分派到不同的类。所以,我可能有一个类调用我们API的一部分,或者另一个类启动服务器,或者发送电子邮件,等等。好吧,为什么要使用ITaskHandler呢??为什么“BillingQuery”还要实现它?您已经获得了.NET反射的好处,并且已经为它创建了对象。只需按原样使用它,而不要求它[ComVisible(true)],也不要求任务调度器知道它。当然不是,所以是例外。只需声明一个C#接口,给它一个Start(字符串数据)方法。实现暂停和恢复是可选的,在实践中肯定不容易实现。考虑一个CopyTaleToCuto停止。不幸的是,TaskSt调器库需要<代码> ITaskHunter-<代码>。我同意这似乎是一个奇怪的要求。它是必需的,这就是运行TaskRegistry.Start()方法的原因。它工作了,完成了任务,现在它需要实际执行任务。但事实并非如此,它再次尝试调用ITaskHandler::Start()。周围没人照顾那个。请注意,TaskRegistry类名错误,应为TaskHandler。它需要处理这个任务。
powershell C:\Windows\Microsoft.Net\Framework64\v4*\RegAsm.exe /codebase '$(ProjectDir)$(OutDir)SchedulableTasks.dll'