HTML Help Workshop returns error after successfully compiled .chm file - cmd

I'm facing a quite weird failure after I successfully compiled a .chm file with HTML Help Workshop's hhc.exe.
I created a documentation of my source code with Doxygen. Doxygen creates if you enable GENERATE_HTMLHELP in the doxygen file:
If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
additional HTML index files: index.hhp, index.hhc, and index.hhk. The index.hhp
is a project file that can be read by Microsoft's HTML Help Workshop (see:
http://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
After Doxygen creates those files, I want to create the .chm file with HTML Help Workshop. For that reason I call hhc.exe in a CMD. After that I can open the .chm file and everything seems fine. But if I ask the CMD for the current errorlevel, it outputs:
"C:\Program Files (x86)\HTML Help Workshop\hhc.exe" index.hhp
Microsoft HTML Help Compiler 4.74.8702
Compiling C:\... folder path ...\index.chm
Compile time: 0 minutes, 0 seconds
37 Topics
346 Local links
12 Internet links
0 Graphics
Created C:\... folder path ...\index.chm, 88,740 bytes
Compression decreased file by 194,682 bytes.
echo %errorlevel%
1
Does anyone have an idea of what the h... is going wrong here and how I can avoid that problem that it's compiled successfully but still returns an error? How can I figure out what's the problem instead of an error "1"?
The problem is that my build server (TFS2015) returns the error and the build is failed.

HTML Help Workshop is installed with 2 main executables:
hhc.exe is the console version of the HTML Help Compiler.
hhw.exe is the Windows GUI version of HTML Help Compiler.
But the compilation of the HTML Help Project (hhp) to Compiled HTML (chm) is not directly done by those two executables.
Both use for compilation hha.dll - the HTML Help Author library - by calling the exported function HHA_CompileHHP.
The exported functions of this library are:
EditHhCtrlObject
EditHhCtrlScript
FreeFilterDIB
HHA_CompileHHP
LoadFilterImage
LoadJpeg
Microsoft has not published any documentation nor the function declarations of those functions as far as I know.
I suppose from some quick tests with hhc.exe that the function HHA_CompileHHP has BOOL as return type which is int and returns on success TRUE, i.e. the value 1, and on failure FALSE, i.e. the value 0. And it looks like hhc.exe uses this return value without inverting the value as exit/return code.
Therefore the errorlevel is 1 on success and 0 on failure.
The tests I made to verify my assumption:
Run HTML Help compiler with name of a project file which does not exist:
hhc.exe index_1.hhp
Unable to open index_1.hhp.
The exit code respectively errorlevel is 0. This error message is printed by hhc.exe because the error message can be found in hhc.exe.
Set read-only file attribute on already existing output file index.chm and run HTML Help compiler:
attrib +r index.chm & hhc.exe index.hhp & attrib -r index.chm
HHC5010: Error: Cannot open "C:... folder path ...\index.chm". Compilation stopped.
The exit code respectively errorlevel is 0. This error message is printed by hha.dll because this error message can be found only in hha.dll.
Rename a *.htm file explicitly specified in index.hhp and run HTML Help Compiler:
ren "file.htm" "renamed file.htm" & hhc.exe index.hhp & ren "renamed file.htm" "file.htm"
Microsoft HTML Help Compiler 4.74.8702
Compiling C:... folder path ...\index.chm
HHC5003: Error: Compilation failed while compiling file.htm.
The following files were not compiled:
file.htm
The exit code respectively errorlevel is 0. This error message is printed also by hha.dll because this error message can be found also only in hha.dll.
All error messages are written to handle STDOUT and not to STDERR as typical for console applications. There was never another value than 0 or 1 assigned to errorlevel which is the reason why I suppose the function HHA_CompileHHP returns a simple boolean value.
Conclusion:
The opposite as usual must be done to evaluate on success/failure of an HTML Help compilation for example by using in the batch file:
"%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe" index.hhp
if not errorlevel 1 exit /B 1
In HTML Help Project file (*.hhp file) in section [OPTIONS] a log file can be specified with Error log file=... into which all messages output by HHA_CompileHHP are written additionally to printing them to STDOUT.
But in this case with Doxygen generating the *.hhp file it would be easier to redirect STDOUT in the batch file to a log file although this is also not really needed because most likely the Team Foundation Server is capturing the messages already to a log. (I don't have Team Foundation Server installed.)

HTML Workshop is a GUI program. When using CMD interactively it does not wait for GUI programs to exit. Therefore there is no error code.
Echo %errorlevel% interactively will never show an error code as well.
This two ways will
Dir && Echo Success || Echo Failure
Dir df:\ & Echo %errorlevel%
[See my answer at Trouble with renaming folders and sub folders using Batch to see what it means]
You will have to read HTML Workshop's documentation to see if it sets an errorlevel. Most GUI programs don't bother.

Related

Script for controlling .exe without using it's GUI? (Unknown API)

I'm looking for a way to run an .exe file and control it by hooking into it's API. The program is Solibri IFC Optimizer (link) and from what I've discovered there is no published documentation about it's API. Is it still possible to control the program without using it's GUI?
My goal is to create a script (.bat or similar) that does the following:
Start program (Solibri IFC Optimizer)
Open file (From hard-coded folder path)
Run process (Optimize IFC file, without zip packaging)
Save file (To hard-coded folder path)
Exit
This script is going to be scheduled and run automatically.
I've searched for similar topics here in Stack Overflow but couldn't find any relevant matches. I'm a novice at this but know some basic programming. This might be silly questions but I would really appreciate any tips and if you guys could point me in the right direction.
Thank you for your very quick replies! I actually got my hands on some documentation about how to control and automate "Solibri IFC Optimizer" by hooking into its API. From what I know, this documentation isn't published somewhere on the internet yet so I would like to share it. This is how to control the program from the Windows command prompt or by using a .bat file:
Solibri IFC Optimizer for Command Line Tool
Example:
c:\Program Files\Solibri\IFCOptimizer>"Solibri IFC Optimizer.exe" -in=d:\temp\model.ifc -out=d:\temp\model_optimized.ifc
Usage:
"Solibri IFC Optimizer.exe" [-license] [-help] [ [-rounding] [-force] -in=dir|file1[;file2;file3;...] [-out=[file|dir [-ifczip|-ifc] [-suffix=_optimized] ]]]
Description:
Solibri IFC Optimizer is used for optimizing Open Standard IFC files.
Optimization is lossless and compression is approximately 5-10%.
Parameter List:
-license : Print license on screen and ignores other options.
-help : Prints this help message and ignores other options.
-rounding : Use floating point rounding.
-force : Force to overwrite existing compressed file(s)
* Default action is to ask for confirmation.
-in : Source folder (optimizes ifc files from the folder)
or file(s) (separated by ';').
-out : Destination file or folder for compressed file(s).
* If destination is a file then -ifczip -ifc & -suffix are ignored.
-ifczip : Forces output file(s) to be compressed .ifczip file(s)
-ifc : Forces output file(s) to be uncompressed .ifc file(s)
By default output file(s) will be compressed .zip file(s).
* Last specified option will be used.
-suffix : Suffix to be added to compressed file(s)
* Default suffix is "_optimized".
After receiving the documentation posted above, I managed to complete the script but I never posted it here. I'll post my solution for other people to find and use:
#echo off
SetLocal EnableExtensions EnableDelayedExpansion
chcp 65001
REM ----- DESCRIPTION -----
echo Optimizing IFC files located in the same directory as the script, using Solibri IFC Optimizer.
REM ----- LINE BREAK (REQUIRES TWO TRAILING BLANK LINES) -----
set br=^
REM ----- ITERATING IFC OPTIMIZATION AND FILE REPLACEMENT -----
set /a count=0
for %%f in (*.ifc) do (
"c:\Program Files\Solibri\IFCOptimizer\Solibri IFC Optimizer.exe" -in="%cd%\%%f" -out="%cd%" -ifc -force
set filename_ext=%%f
set filename=!filename_ext:~0,-4!
move "%cd%\!filename!_optimized.ifc" "%cd%\!filename!.ifc"
set "file_list=!file_list! !filename! !br!"
set /a count += 1
)
msg * "The following !count! IFC files were optimized: !br!!br!"^
!file_list!
exit

SymStore - add multiple files

I am trying to add a bunch of .pdb files to the symbol server using symstore.exe. Not all the .pdb's in the dir, but a selection of them (based on date).
To add them in a single transaction I'm using symstore ... /f '#filelist.txt' where filelist.txt is a file containing the real .pdb one per line - just as the command-line help says:
/f File Network path of files or directories to add.
If the named file begins with an '#' symbol, it is treated
as a response file which is expected to contain a list of
files (path and filename, 1 entry per line) to be stored.
(This info exists only in command-line help to symstore, not in the corresponding online help page.)
This just doesn't work, it stores 0 files. I assume that this feature - adding multiple files from a file list - is just not really implemented.
Does anybody have success adding a list of files in a single transaction with symstore.exe?
Finally, I have figured that out. The feature with # and the response file is actually supported.
After using the symstore's /o switch for debugging output I have noticed a weird character ÿþC in the error output
PS C:\Development\symstore add /f #C:\temp\dllsAndPdbsToAdd.txt /s C:\temp\symstore\ /t AwesomeProject
SYMSTORE MESSAGE: 0 alternate indexers registered
SYMSTORE MESSAGE: LastId.txt reported id 8
SYMSTORE MESSAGE: Final id is 0000000008
SYMSTORE ERROR: Class: Internal. Desc: Failed to index C:\Development\AwesomeProject\ÿþC. Line: 169. Error 32
So I changed encoding of the #C:\temp\dllsAndPdbsToAdd.txt file in Notepad++ to ANSI and it worked.

Windows Dos Command File Not Found (connect:direct Process)

I am using Connect:Direct process to run a DOS command to get the list of files available for collection.
If the files are available in the collection folder then the file details gets redirected to the output file (dirfile.lst). Then Connect:Direct will do a collection for those files and then delete dirfile.lst.
If there are no files in the collection folder it is expected that the dirfile.lst will be empty. And Connect:Direct will collect no files and delete dirfile.lst.
The command which I am using is
(dir "G:\Outbound\EDI\USCOLL_FTP\*" /a-d/oN ) > "F:\Sterling\Connect Direct v4.6.00\Server\program\2172047.dirfile.lst"
The problem which I am facing is when the file filter is . or *.* and if there are no files in the folder then the command throws a response "File Not Found". Connect:Direct process fails when it gets any response from the command. Interestingly I only face this issue is the file filter is . or * for any other file filter I am not getting this "File Not Found" response even though there are no files in the folder.
If I use 2> Null to fix the issue it won't display any other exceptions, hence I don't prefer to use this?
Is there a way I can get rid of File not Found message which I get when I use * and . file filters?
Any help or suggestions will be much appreciated.
It's not pretty, but this should do the trick:
>NUL 2>NUL DIR "G:\Outbound\EDI\USCOLL_FTP\*" /a-d/oN && (DIR "G:\Outbound\EDI\USCOLL_FTP\*" /a-d/oN > "F:\Sterling\Connect Direct v4.6.00\Server\program\2172047.dirfile.lst") || ECHO. > "F:\Sterling\Connect Direct v4.6.00\Server\program\2172047.dirfile.lst"
I know you didn't want to use 2>Nul but it's the best I could get. Hopefully someone will provide a better answer.

How to capture last string in batch file output and to continue or to pause

I am writing a batch file, in which i am calling other batch file using CALL command for compilation. It outputs several outputs. (Success!!!/Building Errors...). I want to capture this last string for comparison and continue for further if success and pause the code if errors are occurred.
Here is the code....
#echo **********Compling %cdir% *******************
call mh123456
output of this compiler batch file(mh123456) is several lines at last it ends with Success!/Building Errors....I want to capture this last line and use if & goto labels for pausing if errors are occurred or continue if success is displayed.
Can you help you out for resolving this...
In file included from SinPWM.c:36:
LVPPG_TEST.h:143:2: warning: no newline at end of file
SinPWM.c: In function `SinPWM':
SinPWM.c:49: parse error before `status_sin'
Deleting ..\Sav_path.bat
1 file deleted 4,096 bytes freed
Building errors ...
This mh123456 batch file calls internally number of batch files but displays above result with at the end Building errors.../Success!!!
#echo **********Compling %cdir% *******************
for /F "delims=" %%a in ('call mh123456') do set "lastLine=%%a"
echo The last line displayed by mh123456 is: "%lastLine%"
Instead of using the building errors / success...i have used the existence of the *.err file type for the compilation failure/success...Now my problem got solved...

How to overcome limit of linking multiple object files in make file

I am new to makefile concept. So please can anyone give me example to overcome the problem of linking too many make files. Because I am getting error "fatal error U1095:" in my make file.
Assuming windows (since on windows, the command line is limited to 128 characters (?! really - sic?!))
I suggest you use #response files for LINK.EXE and or CL.exe etc.
LINK.EXE #response.tmp
You can store all commandline parameters in the text file without any limit.
Update MSDN calls them Command Files

Resources