Dynamics 365 Finance & Operations 绕过CoC调用链限制拓展重写系统类的方法

Dynamics 365 Finance & Operations 绕过CoC调用链限制拓展重写系统类的方法

IShirai_KurokoI

声明:此方法虽然可以有效修改系统类,但是并不是微软推崇的方式,虽然有效,但有可能会影响系统类在将来的更新中的功能,请谨慎使用!

假如我们要修改系统工作流按钮的生成,我们可以这样操作:

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
internal final class OverrideSysWorkflowFormControls extends SysWorkflowFormControls
{
/// <summary>
/// Event handler for consturct method in <c>SysWorkflowFormControls</c>.
/// </summary>
/// <param name = "args">Method args.</param>
[Hookable(false), PostHandlerFor(classStr(SysWorkflowFormControls), staticMethodStr(SysWorkflowFormControls, construct))]
public static void SysWorkflowFormControls_Post_construct(XppPrePostArgs args)
{
FormRun form = Args.getArg(literalStr(_form));

if (form.name() == formStr(FormNeedsAOverride))
{
Args.setReturnValue(OverrideSysWorkflowFormControls::construct(form));
}
}

//下面是复制的原始代码,可以在这里对逻辑进行修改,要带[Hookable(false)]
[Hookable(false)]
public void initControls()
{
#Resource
#ResAppl
#Workflow

FormFunctionButtonControl actionButton;
FormActionPaneControl actionPane;
int i;

// Determine if action pane control exists on form.
for (i=1; i<=formDesign.controlCount(); i++)
{
if ((formDesign.controlNum(i).handle() == classNum(FormActionPaneControl)))
{
actionPane = formDesign.controlNum(i);
break;
}
}

// if we have an action pane, add workflow message bar group directly after it
if (actionPane != null)
{
workflowActionPaneButtonGroup = actionPane.addControl(FormControlType::ButtonGroup, #WorkflowActionPaneButtonGroup);
workflowActionPaneButtonGroup.visible(false);
workflowActionPaneButtonGroup.dataSource(workflowDatasource.name());

actionBarButtonGroup = workflowActionPaneButtonGroup.addControl(FormControlType::MenuButton, #WorkflowActionBarButtonGroup);
actionBarButtonGroup.text("@SYS110684");
actionBarButtonGroup.imageLocation(SysImageLocation::Symbol);
actionBarButtonGroup.normalImage('Workflow');
actionBarButtonGroup.needsRecord(true);
actionBarSubmitButton = actionBarButtonGroup.addControl(FormControlType::MenuFunctionButton, #WorkflowActionBarSubmitButton);
actionBarSubmitButton.menuItemType(MenuItemType::Action);
actionBarSubmitButton.dataSource(workflowDatasource.name());
actionBarSubmitButton.visible(false);
actionBarSubmitButton.enabled(false);

actionCount = 0;
maxActionCount = 10;
for (i=1; i<=maxActionCount; i++)
{
actionButton = actionBarButtonGroup.addControl(FormControlType::MenuFunctionButton, #WorkflowActionMenuFunctionPrefix+int2str(i));
actionButton.menuItemType(MenuItemType::Action);
actionButton.dataSource(workflowDatasource.name());
if (form.name() == formStr(WorkflowWorkList))
{
actionButton.registerOverrideMethod(methodStr(FormFunctionButtonControl, clicked),
identifierStr('menuItem_Clicked'),
form);
}
actionButton.visible(false);
actionButton.enabled(false);
}
}

}
}

原理解析

通过[Hookable(false), PostHandlerFor(classStr(SysWorkflowFormControls), staticMethodStr(SysWorkflowFormControls, construct))]监听SysWorkflowFormControls的类似构造函数(指一个类中可以返回类实例的静态方法,不一定非得是construct),在检测到调用的FormFormNeedsAOverride符合时,替换返回值为当前extend系统类的实例,由于extend可以同名覆盖对应函数,可以实现修改系统类的目标(在满足特定条件时,将系统调用系统类的代码控制流引导至我们的自定义类中,并可以缺省其他不需要修改的函数),实现灵活的系统类逻辑修改,且不对非目标调用的窗体产生影响。

  • 标题: Dynamics 365 Finance & Operations 绕过CoC调用链限制拓展重写系统类的方法
  • 作者: IShirai_KurokoI
  • 创建于 : 2024-11-16 20:08:00
  • 更新于 : 2024-11-23 11:18:38
  • 链接: https://ishiraikurokoi.top/2024-11-16-Dynamics-Bypass-CoC/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
Dynamics 365 Finance & Operations 绕过CoC调用链限制拓展重写系统类的方法