# AutoLinker
**Repository Path**: dulang104/AutoLinker
## Basic Information
- **Project Name**: AutoLinker
- **Description**: AutoLinker支持库,支持不同源文件使用不同的Linker,调试编译时动态与静态ec自动切换,易语言AI Agent。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-17
- **Last Updated**: 2026-04-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# AutoLinker
AutoLinker支持库,通过各种方法实现以下功能:
* 不同的.e源文件使用不同的链接器
* 调试、编译时动静态ec自动切换
* 重写核心库函数
## 使用方法
编译后将AutoLinker.fne放在e的lib目录中,并启用AutoLinker支持库。
### ⭐不同的.e源文件使用不同的链接器
此功能实现针对不同.e源文件使用不同链接器,**再也不用来回手动切换链接器了**。
**使用方法**
* 在`e\AutoLinker\Config`中,存放`link.ini`的各种版本,命名如:`vc6.ini`、`vc2017.ini`、`vc2022.ini`等。

* `当前源文件所对应的链接器`。**!!!此位置新版本已改到编译菜单下!!!**

### ⭐调试、编译时动态静态ec自动切换
此功能实现一对ec文件,在调试、编译时,自动进行切换,如VMP的SDK、ExDui模块,编译要用Lib声明链接进exe,调试用Dll声明(因为无法e无法在调试时使用Lib),来回切换模块非常麻烦,所以实现了此功能。
支持版本`5.71`、`5.95` (其他的未测试但应该行)
**使用方法**
* 在`e\AutoLinker\ModelManager.ini`中添加内容既可,格式如下,一行一个,**注意俩ec需要放在同一个文件夹中**,左侧为调试模块、右侧为编译模块
```
VMPSDK.ec=VMPSDK_LIB.ec
```
## AutoLinker AI 功能使用说明
### ⭐右键菜单 AI 功能
1. `AI优化函数` 对当前函数做等价优化。
2. `AI为当前函数添加注释`
3. `AI翻译当前函数+变量名` 将函数名、参数名、局部变量名翻译/重命名为英文 `lowerCamelCase`。
4. `AI翻译选中文本`
5. `AI按当前页类型添加代码` 根据“当前页类型 + 你的需求 + 当前页上下文”生成新增代码。
### ⭐AI 会话页签(内置 TAB)
- 支持本地 MCP 工具调用(如读取当前页代码、搜索代码、搜索支持库内容、搜索模块内容、弹出代码修改对话框)。
## AutoLinker 本地 MCP 文档
### ⭐服务地址
- 默认监听:`http://127.0.0.1:19207/mcp`
- 如果端口 `19207` 被占用,会自动尝试 `19208` 起的后续端口。
- 启动成功后,E 输出窗口会打印类似日志:
```text
[AutoLinker][LocalMCP] listening on http://127.0.0.1:19207/mcp
```
### ⭐协议说明
- 协议:`JSON-RPC 2.0`
- MCP `initialize` 返回的 `protocolVersion` 为:`2024-11-05`
- 当前支持的方法:
- `initialize`
- `notifications/initialized`
- `ping`
- `tools/list`
- `tools/call`
### ⭐客户端接入 JSON 示例
#### 通用 HTTP MCP 配置
- 如果你的 MCP 客户端支持基于 HTTP 的 MCP,可直接配置为:
```json
{
"mcpServers": {
"AutoLinker": {
"transport": "streamable_http",
"url": "http://127.0.0.1:19207/mcp"
}
}
}
```
#### 某些客户端的简化写法
- 有些客户端不要求显式写 `transport`,可写成:
```json
{
"mcpServers": {
"AutoLinker": {
"url": "http://127.0.0.1:19207/mcp"
}
}
}
```
#### 如果端口被自动顺延
- 当 `19207` 被占用时,AutoLinker 会自动尝试后续端口,所以客户端配置中的 `url` 需要与 E 输出窗口中的实际监听地址保持一致,例如:
```json
{
"mcpServers": {
"AutoLinker": {
"transport": "streamable_http",
"url": "http://127.0.0.1:19208/mcp"
}
}
}
```
#### 说明
- AutoLinker 当前提供的是本地 HTTP MCP 服务,不是 `stdio` 型 MCP。
- 如果某个客户端只支持 `stdio` 方式而不支持 HTTP/Streamable HTTP,则不能直接接入当前版本的 AutoLinker MCP。
### ⭐HTTP 访问说明
- `GET /` 或 `GET /mcp`
- 返回服务健康信息和当前 `mcp_endpoint`
- `POST /mcp`
- 发送 JSON-RPC 请求
- `OPTIONS /mcp`
- CORS 预检
### ⭐tools/list 返回的当前公开工具
#### 1. 当前页相关
- `get_current_page_info`
- 获取当前 IDE 页名称、页类型以及名称解析来源。
- `get_current_page_code`
- 获取当前 IDE 页完整代码,同时返回当前页名称和页类型。
#### 2. 模块相关
- `list_imported_modules`
- 列出当前项目导入的易模块/ECOM 路径。
- `get_module_public_info`
- 获取指定模块的公开接口信息。
- 说明:这里返回的是模块公开接口/伪代码参考,不是正常 IDE 源码页。
- `search_module_public_info`
- 在模块公开接口信息中搜索关键词。
- 说明:搜索结果同样属于公开接口/伪代码参考。
#### 3. 支持库相关
- `list_support_libraries`
- 列出当前 IDE 已选支持库。
- 返回支持库基本信息、文件路径解析结果以及原始信息文本。
- `get_support_library_info`
- 获取单个支持库公开信息。
- 优先通过支持库文件 `GetNewInf/lib2.h` 结构解析命令、常量、数据类型等;无法定位文件时退回 IDE 文本。
- `search_support_library_info`
- 在支持库公开信息中搜索关键词。
#### 4. 程序树/项目结构相关
- `list_program_items`
- 列出程序树中的程序集、类模块、全局变量、自定义数据类型、DLL 命令、窗口、资源等项目。
- 支持按 `kind`、名称过滤,并可选附带代码。
- 说明:这里通过程序树抓到的代码是伪代码参考,结构可能与正常 IDE 页略有差异。
- `get_program_item_code`
- 按精确名称获取某个程序树项目的整页代码。
- 说明:返回代码属于伪代码参考。
- `switch_to_program_item_page`
- 按精确名称切换到某个程序集/类/资源页面。
- 只负责切页,不返回代码。
#### 5. 项目搜索相关
- `search_project_keyword`
- 调用 IDE 整体搜索,在项目内搜索关键词。
- 返回匹配页名、页类型、行号、显示文本和 `jump_token`。
- `jump_to_search_result`
- 使用 `search_project_keyword` 返回的 `jump_token` 精确跳转到某一条结果。
#### 6. 本地交互相关
- `request_code_edit`
- 弹出本地代码编辑确认窗口,返回用户确认后的代码。
### ⭐tools/call 参数说明
- 调用格式:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_current_page_info",
"arguments": {}
}
}
```
- `params.name`
- 工具名称
- `params.arguments`
- 工具参数对象
### ⭐常用调用示例
#### 列出工具
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
```
#### 获取当前页信息
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_current_page_info",
"arguments": {}
}
}
```
#### 获取当前页代码
```json
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_current_page_code",
"arguments": {}
}
}
```
#### 搜索项目关键词
```json
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "search_project_keyword",
"arguments": {
"keyword": "subWinHwnd",
"limit": 20
}
}
}
```
#### 跳转到某条搜索结果
```json
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "jump_to_search_result",
"arguments": {
"jump_token": "v1:1:1224804111:315:0:0"
}
}
}
```
### ⭐会改变 IDE 当前页的工具
- 以下工具具有副作用,会导致当前 IDE 页面或光标位置发生变化:
- `get_program_item_code`
- `switch_to_program_item_page`
- `jump_to_search_result`
- 使用这些工具前后,不要假定当前页仍保持不变。
### ⭐关于“伪代码参考”的说明
- 以下来源拿到的代码/结构,不等同于 IDE 中用户正在编辑的原始页内容:
- `get_module_public_info`
- `search_module_public_info`
- `list_program_items` 中附带的代码
- `get_program_item_code`
- `search_project_keyword` 的结果文本及其后续关联代码
- 这些内容适合做定位、检索、接口参考,但不应当当作 100% 原样源码。
## 其他功能
### ⭐重写核心库函数
此功能可用现代C++方法替换核心库函数,大幅**提升函数性能**,同时也可**防针对e函数特征的破解**以及**免杀**的效果。同理你也可以覆盖第三方库的函数,比如特殊功能支持库等等。
**使用方法**
* 在IDA中查找正确的`函数签名`并声明,打开`krnln_static.lib`中的`LibFn.obj`,大部分核心库函数在此实现

* 可以在黑月核心库的开源中参考其代码进行新的实现
https://github.com/zhongjianhua163/BlackMoonKernelStaticLib
* 在自己的Lib中实现函数,实现请参考TestCore项目。
```c
///
/// 使用C++20(需VC2022)方法替代核心库的寻找文本,大约是核心库的300%速度,未仔细测试,仅为覆盖实现的例子
///
///
///
///
///
extern "C" void __cdecl krnln_fnInStr(PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf) {
//TODO 你还可以在这里添加VMP标志
// 获取输入字符串
std::string_view inputString = pArgInf[0].m_pText;
std::string_view searchString = pArgInf[1].m_pText;
// 空字符串检查
if (inputString.empty() || searchString.empty()) {
pRetData->m_int = -1;
return;
}
// 确定开始搜索的位置
size_t searchStartPos = (pArgInf[2].m_dtDataType == _SDT_NULL || pArgInf[2].m_int <= 1) ? 0 : pArgInf[2].m_int - 1;
// 搜索指定字符串
auto searchResult = (pArgInf[3].m_bool) ?
std::search(
inputString.begin() + searchStartPos, inputString.end(),
searchString.begin(), searchString.end(),
[](char c1, char c2) { return std::tolower(c1) == std::tolower(c2); }
) :
std::search(
inputString.begin() + searchStartPos, inputString.end(),
searchString.begin(), searchString.end()
);
// 设置返回位置,如果找到则返回位置,否则返回-1
pRetData->m_int = (searchResult != inputString.end()) ? std::distance(inputString.begin(), searchResult) + 1 : -1;
}
```
* 使用Release编译为32位lib,将lib的路径添加到`e\AutoLinker\ForceLinkLib.txt`中,你可以指定链接器才使用此Lib,也可以单独一行指定在所有链接器中使用
```
vc2022+pf=D:\git\X\Release\TestCore.lib
D:\git\X\Release\TestCore.lib
```
**注意**:例子TestCore使用C++20,必须使用VC2022链接器才可链接
* 进行静态编译既可,会提示如下内容,不会影响代码运行
```
krnln_static.lib(Libfn.obj) : warning LNK4006: _krnln_fnBAnd 已在 TestCore.lib(a1.obj) 中定义;已忽略第二个定义
krnln_static.lib(Libfn.obj) : warning LNK4006: _krnln_fnSin 已在 TestCore.lib(a1.obj) 中定义;已忽略第二个定义
krnln_static.lib(Libfn.obj) : warning LNK4006: _krnln_fnInStr 已在 TestCore.lib(a1.obj) 中定义;已忽略第二个定义
nafxcw.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已在 LIBCMT.lib(new_scalar.obj) 中定义;已忽略第二个定义
nafxcw.lib(afxmem.obj) : warning LNK4006: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) 已在 LIBCMT.lib(delete_scalar.obj) 中定义;已忽略第二个定义
C:\Users\aiqin\OneDrive\Code\模块\测试空.exe : warning LNK4088: 因 /FORCE 选项生成了映像;映像可能不能运行
正在写出可执行文件
```
**注意**
* 此方法自动开启链接器的/FORCE忽略冲突
* 自己写的LIB文件需要关闭链接器/GL参数,否则会触发二次链接导致忽略由AutoLinker调整的Lib顺序。
### ⭐按实现鼠标后退键后退到上个修改
没啥可说的,其他IDE都有的功能,个人喜好。