尝试构建 XLL“此程序无法在 DOS 模式下运行”

Trying to build an XLL "This program cannot run in DOS mode"

提问人:C. Cristi 提问时间:10/21/2022 最后编辑:C. Cristi 更新时间:10/28/2022 访问量:348

问:

我一直在尝试构建一个简单的 XLL,它只会使用硬编码的命令行创建一个进程。这是我的代码:

#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: {
        LPSTARTUPINFOA si = new STARTUPINFOA();
        LPPROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        CreateProcessA(NULL, (LPSTR)"notepad.exe", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, si, pi);
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

基本上是创建 DLL,然后将其重命名为 XLL。我正在使用 Visual Studio 2019,以下是我用于编译的标志:

/JMC /permissive- /Yu"pch.h" /ifcOutput "x64\Debug\" /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc142.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "EVIL_EXPORTS" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MT /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Evil.pch" /diagnostics:column 

我也在使用 Professional Excel 2013 64 位。可能是什么问题?即使使用 Excel 2016 64 位和 Office 365,也一直在尝试。版本 16.01。

更新: 从本质上讲,是的,该语句可能应该出现在 Excel 电子表格中,但至少我希望“记事本 .exe”运行,但这不会发生。

以下是链接器标志:

/OUT:"C:\Users\Cristi Cretan\source\repos\XLLCalc\Release\XLLCalc.xll" /MANIFEST /LTCG:incremental /NXCOMPAT /PDB:"C:\Users\Cristi Cretan\source\repos\XLLCalc\Release\XLLCalc.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"C:\Users\Cristi Cretan\source\repos\XLLCalc\Release\XLLCalc.lib" /DEBUG /DLL /MACHINE:X86 /OPT:REF /SAFESEH /INCREMENTAL:NO /PGD:"C:\Users\Cristi Cretan\source\repos\XLLCalc\Release\XLLCalc.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"Release\XLLCalc.xll.intermediate.manifest" /LTCGOUT:"Release\XLLCalc.iobj" /OPT:ICF /ERRORREPORT:PROMPT /ILK:"Release\XLLCalc.ilk" /NOLOGO /TLBID:1 
C++ Excel DLL

评论

0赞 Sedenion 10/23/2022
一些猜测:也许是 32 位 DLL 和 64 位办公室的混合,反之亦然?否则,根据文档,XLL 应该至少有一个导出。因此,也许Excel缺少该消息,因此可以解决令人困惑的错误消息?xlAutoOpen
0赞 C. Cristi 10/23/2022
@Sedenion DLL 也是 64 位,但是我有一个朋友,我们找到了这个 github 项目 (github.com/CuckooEXE/PopCalc) 我们都克隆了它并构建了它,对他来说它可以工作,现在我得到了他的确切版本的 Excel(Office 365 16.01 64 位),对我来说它仍然不起作用。这个 github 也有一个 test.exe 也适用于我,所以 DLL 必须工作,它可能是来自 excel 的东西?
0赞 C. Cristi 10/23/2022
@Sedenion 但是,我将DLL转换为XLL所做的只是重命名它。但从我在互联网上看到的情况来看,这应该不是问题
0赞 C. Cristi 10/23/2022
@Sedenion在他的 PC 上,它仍然在电子表格中显示消息,但至少它打开了“calc.exe”
1赞 DS_London 10/27/2022
通过将文件称为 XLL,Excel 将假定它是一个加载项,并查找最小数量的入口点(请参阅 Excel SDK)。这可能是一个措辞不当的错误,因为 Excel 不知道如何处理正在打开的文件。我不清楚......如果注释掉尝试创建进程的三行,是否仍然会遇到相同的错误?

答:

0赞 DS_London 10/28/2022 #1

缺少一些东西:

  • STARTUPINFO 初始化(帽子提示@CristiFati)
  • xlAutoOpen 入口点,带 C 外部链接

此代码会编译(至少对我来说),并在加载时显示记事本(我确实收到缺少证书的安全警告,但这可能是我锁定的 Excel 设置)。xll

//MyXll.cpp    
#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {     
        STARTUPINFO si;
        PROCESS_INFORMATION pi;

        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));

        if( CreateProcess(TEXT("c:\\windows\\system32\\notepad.exe"), NULL, 
                  NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) )
        {
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        }
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

extern "C" __declspec(dllexport) int WINAPI xlAutoOpen(void)
{
    return 1;
}

我已经静态地链接到 C 运行时(在“代码生成”下,选择“多线程调试”),并具有 、 和预处理器定义。在“高级”属性中,“目标文件扩展名”设置为 。我没有使用预编译的标头。_DEBUG_WINDOWSUNICODE_USRDLL.xll

使用 MSVC Pro 22 编译并加载到 Excel 16 64 位中。

Excel 将期望找到入口点,除非存在,否则不会识别入口点。该函数不必执行任何操作(尽管实际上这是函数注册发生的地方)。xlAutoOpenxllxll

如果您不提供任何 Excel 功能,则无需包含或链接任何 Excel SDK 元素(例如 、)。xlcall.hxlcall32.lib

链接到文档。