如果在批处理过程中 nmake 失败,则返回错误和电子邮件

Posted

技术标签:

【中文标题】如果在批处理过程中 nmake 失败,则返回错误和电子邮件【英文标题】:Return Error and email if nmake fails during batch 【发布时间】:2015-02-02 09:16:13 【问题描述】:

我正在尝试创建批处理以在 Windows 下实现 Nightly 构建。我设法在发行版中编译并通过脚本自动生成调试。

但是现在我希望在编译过程中出现错误时得到通知,如果编译失败需要返回电子邮件。这就提出了以下问题:

我会返回错误 nmake 吗?或者更确切地说,如果它失败了批​​次本身?

如果是这样,我如何在文本文件或电子邮件中返回此错误?

我在 à Windows Server 2012 下运行并使用任务调度程序来自动化。这是我的批次(已编辑)

@echo on
echo[
set rel=release
@echo ####### COMPILATION CORE (DEBUG / x86) #######
echo[
cd C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### delete cache  #######
rm -R *
@echo ####### Generation of Makefile  #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
cmake -DCMAKE_BUILD_TYPE=Debug -G"NMake Makefiles" ../
if %errorlevel% neq 0 goto mailcmaked 

@echo ####### compilation of core  #######
echo[
nmake
if %errorlevel% neq 0 goto mailnmaked
pause

@echo ####### COMPILATION CORE(RELEASE / x86) #######
echo[
cd C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### Suppression du CACHE  #######
rm -R *
@echo ####### Generation of Makefile  #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
cmake -DCMAKE_BUILD_TYPE=Release -G"NMake Makefiles" ../
if %ERRORLEVEL% neq 0 goto mailcmaker

@echo ####### Compilation of CORE  #######
echo[
>"..\log\buildRel.log" nmake
if %errorlevel% neq 0 goto mailnmaker
pause

:mailcmaked
echo Error!
sendEmail -f from@mail.com -t someone@mail.com -m "cmake debug failed" -s 192.168.x.x
exit 1

:mailnmaked
echo Error!
sendEmail -f from@mail.com -t someone@mail.com -m "nmake debug failed" -s 192.168.x.x
exit 1

:mailcmaker
sendEmail -f from@mail.com -t someone@mail.com -m "cmake release failed" -s 192.168.x.x
exit 1

:mailnmaker
grep -Eo '.0,20error.0,100' ..\log\buildRel.log > ..\log\mailBuild.txt
sendEmail -f from@mail.com -u "build failed" -t someone@mail.com -m "nmake release failed" -a ..\log\mailBuild.txt -s 192.168.x.x
exit 1

编辑

我从您的示例中汲取灵感编辑了我的脚本,现在效果很好(目前仅适用于 :mailnmaker 部分)。我用 grep 命令组织我的输出。

对于邮件问题,我刚刚安装了 sendEmail 并将其放入我的 Windows PATH 中,这样就可以了。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

首先,没有可让您发送电子邮件的本机命令。不过,您可以使用CDO.Message 使用 Windows 脚本(VBScript 或 JScript)编写脚本。将 Windows 脚本宿主合并到批处理脚本中的最简单的方法是 use a hybrid script。

如果cmakenmake 以非零状态退出,您可以使用conditional execution 触发发送电子邮件功能。

这是一个帮助您入门的示例框架。 请注意,这是未经测试的,可能会被破坏。但无论如何,它至少应该为您提供一个起点。

(另请注意,我将rm -R * 替换为本机Windows 命令,并且cmakenmake 的输出将重定向到%temp%\build.log,以便在需要时包含在电子邮件中。如果您希望输出回显到控制台,如果你安装了 cygwin 或 gnuwin32 或类似的,你可能必须使用tee -a;或者可能合并this scripted imitation。)

@if (@CodeSection == @Batch) @then

@echo on
echo[

@echo ####### COMPILATION CORE (DEBUG / x86) #######
call :make Debug || exit /b %ERRORLEVEL%

@echo ####### COMPILATION CORE(RELEASE / x86) #######
call :make Release || exit /b %ERRORLEVEL%

goto :EOF

:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:make <Release|Debug>
:::::::::::::::::::::::::::::::::::::::::::::::::::::::

echo[
cd /d C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### delete cache  #######
for /d %%I in (*) do rmdir /q /s "%%~I"
del /q /y *
@echo ####### Makefile  #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"

:: use conditional execution to send an email if cmake exits non-zero
>"%temp%\build.log" cmake -DCMAKE_BUILD_TYPE=%1 -G"NMake Makefiles" ../ || (
    call :sendmail cmake %1 %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)

@echo ####### compilation of core (debug/x86)  #######
echo[
:: use conditional execution to send an email if nmake exits non-zero
>"%temp%\build.log" nmake || (
    call :sendmail nmake %1 %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)
goto :EOF

:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:sendmail <name> <buildtype> <errorlevel>
:::::::::::::::::::::::::::::::::::::::::::::::::::::::

cscript /nologo /e:JScript "%~f0" "%~1" "%~2" "%~3" "%temp%\build.log"
exit /b %~3

:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: end batch / begin JScript
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
@end

var buildstep = WSH.Arguments(0),
    buildtype = WSH.Arguments(1),
    errorlevel = WSH.Arguments(2),
    buildlog = WSH.Arguments(3),
    oSH = WSH.CreateObject('WScript.Shell'),
    fso = WSH.CreateObject('Scripting.FileSystemObject');

function SendEMail(config) 
    try 
        var oMsg = WSH.CreateObject("CDO.Message");
        for (var i in config) oMsg[i] = config[i];
        oMsg.Send();
    
    catch(e) 
        var profile = oSH.Environment('Process')('USERPROFILE'),
            alert = fso.CreateTextFile(profile + '\\Desktop\\builderr.log', 1);

        alert.WriteLine(buildstep + ' build type ' + buildtype
            + ' failed.  Email failed.  Everything is broken.  I give up.');

        alert.WriteLine(getLog(20));
        alert.Close();
    


function getLog(lines) 
        log = fso.OpenTextFile(buildlog, 1),
        contents = [];

    while (!log.AtEndOfStream) 
        contents.push(log.ReadLine());
        if (contents.length > lines) contents.shift();
    
    log.Close();
    return contents.join('\n');


SendEMail(
    From: "from@example.com",
    To: "to@example.com",
    Subject: "Build failed",
    TextBody: buildstep + " build type " + buildtype
        + " failed with error code " + errorlevel
        + '\n\nLast 20 lines of messages from ' + buildlog + ':\n\n' + getLog(20)
);

【讨论】:

哇。谢谢。这对我来说有点复杂^^但我明天会试试。

以上是关于如果在批处理过程中 nmake 失败,则返回错误和电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

接口返回失败是啥意思

如果一条记录在 oracle 中插入失败,则避免 jdbc 批量插入失败

NMake 在使用 $(shell) 时返回错误

如何让 nmake 克服错误(make -k 的行为)

尝试编译 argon2_elixir 时,nmake 失败

NMAKE:致命错误 U1077:“cl.exe”:返回代码“0x1”停止。在命令提示符下