[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 bailong360 于 2017-6-13 16:37 编辑

很cool,而且效率很高!
能否请教一下原理?

再提一个建议:如楼上所说只能加载一个dll局限性很大,除非再把ext.dll做成一个加载器.然而这样不如让cmdex提供一个load命令,用来加载其他dll.这样不同开发者开发的dll就可以同时使用
------------------------
测试了一下 发现有一个bug
  1. @echo off
  2. set a=%s%
  3. my%__%cmd %a%
  4. pause
复制代码
这样一段代码,执行后输出的是
  1. cmd:mycmd
  2. lastcmdline:my%__%cmd %a%
  3. 请按任意键继续. . .
复制代码
%__%和%a%没有被扩展,不过"cmd:mycmd"倒是得到了正确结果 望改进

TOP

本帖最后由 bailong360 于 2017-6-15 12:18 编辑

回复 9# misaki
前段时间备战高考 就没怎么来了
输入cmdex其实就看到你的ID了/手动斜眼

其实想到了你可能是hook了字符串处理的函数...但是觉得以这些函数的使用频率对效率影响应该比较大,就排除了这种可能性......看来功力尚浅啊
不过这倒是给了我一个新思路

交给开发者来处理命令行感觉有利有弊吧

TOP

本帖最后由 bailong360 于 2017-6-16 22:21 编辑

回复 11# misaki
测试过各系统下的兼容性吗? 感觉这个很有戏  

试着编写了一个AddCmd  tcc编译通过
将变量扩展和参数都处理了一下,应该是个通常情况下比较友好的接口
  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <shellapi.h>
  4. #define DLL_EXPORT __declspec(dllexport)
  5. #define HANDLED     0
  6. #define UNHANDLED   1
  7. #define MAX_CMD_LENGTH 512
  8. typedef struct cmdTable {
  9.     wchar_t cmd[MAX_CMD_LENGTH];
  10.     int     (*func)(int, wchar_t *[]);
  11.     struct  cmdTable *next;
  12. } CMDTABLE;
  13. DLL_EXPORT int ExtCallBack(wchar_t *, wchar_t *);
  14. char* WcharToChar(wchar_t *wstr);
  15. int AddCmd(int argc, wchar_t *cmdline[]);
  16. CMDTABLE cmd_Load = {L"AddCmd", AddCmd, NULL};
  17. CMDTABLE *head = &cmd_Load;
  18. CMDTABLE *tail = &cmd_Load;
  19. DLL_EXPORT int ExtCallBack(wchar_t *cmd, wchar_t *cmdline)
  20. {
  21.     CMDTABLE *current = head;
  22.     do {
  23.         if (!wcsnicmp(cmd, current->cmd, wcslen(current->cmd))) {
  24.             int       argc;
  25.             wchar_t **argv;
  26.             wchar_t newcmdline[MAX_CMD_LENGTH];
  27.             ExpandEnvironmentStringsW(cmdline, newcmdline, MAX_CMD_LENGTH + 1);
  28.             newcmdline[wcslen(newcmdline) - 2] = '\0'; //去除末尾的\n
  29.             argv = CommandLineToArgvW(newcmdline, &argc);
  30.             current->func(argc, argv);
  31.             LocalFree(argv);
  32.             return HANDLED;
  33.         }
  34.         current = current -> next;
  35.     } while (current != NULL);
  36.     return UNHANDLED;
  37. }
  38. char* WcharToChar(wchar_t *wstr)
  39. {
  40.     int len   = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
  41.     char *str = (char *)malloc(len * sizeof(char));
  42.     WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
  43.     return str;
  44. }
  45. int AddCmd(int argc, wchar_t *argv[])
  46. {
  47.     if (argc < 4) {
  48.         puts("Usage: AddCmd YourCmd YourDll YourFunc");
  49.         puts("**YourFunc should be defined like this \"int YourFunc(int argc, wchar_t *argv[])\"");
  50.         return 0;
  51.     }
  52.     HMODULE hDLL   = LoadLibraryW(argv[2]);
  53.     char *funcName = WcharToChar(argv[3]);
  54.     void *func     = (void *)GetProcAddress(hDLL, funcName);
  55.    
  56.     if (hDLL == NULL) {
  57.         fprintf(stderr, "ERROR:can't load dll \"%S\"", argv[2]);
  58.         free(funcName);
  59.         return 0;
  60.     } else if (func == NULL) {
  61.         fprintf(stderr, "ERROR:can't load func \"%s\"", funcName);
  62.         free(funcName);
  63.         return 0;
  64.     }
  65.     tail->next = (CMDTABLE *)malloc(sizeof(CMDTABLE));
  66.     wcscpy(tail->next->cmd, argv[1]);
  67.     tail->next->func = (void *)GetProcAddress(hDLL, funcName);
  68.     tail->next->next = NULL;
  69.     tail = tail->next;
  70.     free(funcName);
  71.     return 0;
  72. }
复制代码

TOP

回复 13# misaki
刚刚又想到了一个问题
ExpanEnvironmentStringsW只能扩展以%%包裹的变量,!!好像不好处理- -

TOP

返回列表