How to use an OR statement in a Post-Build event? - visual-studio-2010

I am trying to use a conditional with an OR in a Post-Build event, but so far, I have had not luck. The following does not work:
if not "$(ConfigurationName)" == "Debug" or not "$(ConfigurationName)" == "Release" (
but this works:
if not "$(ConfigurationName)" == "Debug" (
With the first one, I get an exist code 4.

It seems like there is no provision for OR/AND in conditionals in Pre-Post Build events, at least according to its lack of documentation over here: http://technet.microsoft.com/en-us/library/bb490920.aspx
You would have to re-write your IF statement to do what you would want to do.
if not "$(ConfigurationName)" == "Debug" (
rem do something
) else if not "$(ConfigurationName)" == "Release" (
rem do the same thing as above
)
Hope that helps, though your conditions don't make sense to me. :-)

If you want to execute some logic in a Post-Build event where the ConfigurationName is not "Debug" or "Release", try the following:
if not "$(ConfigurationName)" == "Debug" (if not "$(ConfigurationName)" == "Release" (***ADD LOGIC HERE - ConfigurationName is not "Debug" or "Release"***))

Related

How do I set test.testLogging.showStandardStreams to true from the command line?

It is convenient to debug some of external libraries and even internal code while writing unit tests by reviewing the logging on stdout.
While I can add test.testLogging.showStandardStreams = true to the build.graddle file, I'd rather do something less permanent, such as setting this flag from the command line execution of gradle.
I've tried several approaches, none seem to work:
gradle test -Dtest.testLogging.showStandardStreams=true
gradle test -Ptest.testLogging.showStandardStreams=true
And other variations of those options by changing the property string. Nothing seems to do the trick.
How do I set test.testLogging.showStandardStreams=true from the command line?
There is no built-in way to set build model properties from the command line. You'll have to make the build script query a system or project property that gets passed in via -D or -P, respectively.
Just use environment variables:
test {
testLogging.showStandardStreams = (System.getenv('PRINTF_DEBUG') != null)
}
Now run your test case like this:
PRINTF_DEBUG=1 ./gradlew test --tests=com.yourspace.yourtest
This will run enable console output and just run one single test case. You often not want to enable console output for the entire test suite because of the noise generated.
You can override it like this
gradle -Doverride.test.testLogging.info.showStandardStreams=true test
or you can add this to your gradle.properties either in the project or in ~/.gradle/gradle.properties
systemProp.override.test.testLogging.info.showStandardStreams=true

Process execution and logging of output of subsubprocesses

We use jenkins for build automation of a Visual Studio 2008 C++ Project.
In essence it's a series of calls of:
devenv solution_name /build configuration_name [/Project project_name]
which works fine in general.
To run everything out of a dos box I wrote a scala wrapper, which does the same with ProcessBuilder. It works, but I have the problem, there is not output on the console.
My guess: devenv starts a bunch of processes to compile and linke the projects in parallel. My scala programm only outputs the stdout and stderr of the devenv process, which is none. All the other output of the subprocesses is shot into nirvana.
for the sake of completness the source snippet:
def buildProject(branch: String, mode: Mode) = {
import scala.sys.process._
val lb = new ListBuffer[String]()
lb.append("devenv")
lb.append(solution)
lb.append(mode.cmd)
lb.append(config.asString)
if (!"".equals(project))
lb.append(project)
val printLogger = ProcessLogger(line => println(line), line => println(line))
val errorLevel = Process(lb.toList, new File(branch, work.sv)) ! printLogger
if (errorLevel != 0)
throw new RuntimeException("Project build failed.")
}
The List used to start the process looks like:
List(devenv, Libraries/Libraries.sln, /rebuild, Release)
Is there a way to record/output the output of the subprocesses?

Under what conditions does the stringizing preprocessor operator add an _T?

The following code doesn't compile in my VC++ 2010 project:
define MY_MAJOR_VERSION 20
define OLESTR_(str) L##str
define MOLE( STR ) OLESTR_(#STR)
define MAKE_STR(STR) MOLE(STR)
REGMAP_ENTRY(MAKE_STR(VERSION), MAKE_STR(MY_MAJOR_VERSION))
VERSION is NOT a macro definition, just text. In the end, I want:
REGMAP_ENTRY(L"VERSION", L"20")
but what I get, when I compile in Debug mode is:
REGMAP_ENTRY(L"VERSION", LL"20")
I'm thinking it's a project setting because I've used that in debug mode in other situations, but never with this problem. Is there a VC++ 2010 setting that would cause the stringizing operator to insert an L or _T?
For me, this (note that I changed MAKE_STR to MAKE_OLESTR - I assume that was a typo in the code posted in the question):
#define MY_MAJOR_VERSION 20
#define OLESTR_(str) L##str
#define MOLE( STR ) OLESTR_(#STR)
#define MAKE_OLESTR(STR) MOLE(STR)
REGMAP_ENTRY(MAKE_OLESTR(VERSION), MAKE_OLESTR(MY_MAJOR_VERSION))
preprocesses to (as shown by cl /E test.c):
REGMAP_ENTRY(L"VERSION", L"20")
which seems to be what you want.
You may want to post something that can reproduced using a command line compile.

Preventing debug code going into production using Progress 4GL?

How would you prevent chunks of debugging code from accidentally leaking into production enviroment when using Progress 4GL?
I usually just publish a special event - debug-message. In my dev environment there's a menu item in the application which will fire up a window which susbscribes to debug-message anywhere and displays any messages generated. So I can insert debug-messages into my code and then open the window if I want to see the messages. If I forget to tidy up the debug code then the live users don't see any messages, although I can still open the debug window to see what's going on.
( The webspeed version of this would just write the output to an OS file )
If your test database and production databases have different names, you could use this code:
IF DBNNAME = "TESTDB" THEN
DO:
<DEBUG CODE>
END.
Similar to my other answer about the assertions, you can setup an include that will be empty on production sites containing the debug flag. On development sites you just need to define the value so that your debugging code is included in your program.
By wrapping code in a preprocessor the compiler will omit the debug code altogether when you compile it onto a production site.
&if defined( debugalert ) <> 0 &then
&endif
You would then use the "&global-define debug" in versions of the code you want to contain the debug code. Not defining "debug" should cause the compiler to omit the code.
/* debug.i omit the following on production */
&GLOBAL-DEFINE DEBUGALERT
/* test.p */
{debug.i}
DEF VAR h_ct AS INT NO-UNDO
DO h_ct = 1 TO 10:
&IF DEFINED( DEBUGALERT ) <> 0 &THEN
MESSAGE "debug message" h_ct.
<debug code goes here>
&ENDIF
END.
A solution is based on the assumption that development enviroment has a unique propath entry that is not available in other enviroments and code is recompiled when moved over:
&IF DEFINED(DEBUGGING) = 0 &THEN
&IF PROPATH MATCHES '*development*' &THEN
&GLOBAL-DEFINE DEBUGGING TRUE
&ELSE
&GLOBAL-DEFINE DEBUGGING FALSE
&MESSAGE Remove debugging: search for DEBUG within the code.
&ENDIF
&ENDIF
&IF DEFINED(DEBUGGING_STARTED) = 0 &THEN
&GLOBAL-DEFINE DEBUGGING_STARTED TRUE
IF {&DEBUGGING} THEN
DO:
&ELSE
END.
&UNDEFINE DEBUGGING_STARTED
&ENDIF
Usage
Save file as "debug" (without extension) to a directory pointed at by propath, then:
{debug}
/* some debugging code here */
{debug/}

Can a Win32 console application detect if it has been run from the explorer or not?

I have to create a console application which needs certain parameters. If they are missing or wrong I print out an error message.
Now the problem: If someone starts the program from the explorer by double-clicking the console window disappears immediately. (But the application is not entirely useless from the explorer, you could drag files onto it and it would work)
I could always wait for a keypress, but I don't want that if the user did start it from the command line.
Is there some way to distinguish between these situations?
See http://support.microsoft.com/kb/99115, "INFO: Preventing the Console Window from Disappearing".
The idea is to use GetConsoleScreenBufferInfo to determine that the cursor has not moved from the initial 0,0 position.
Code sample from #tomlogic, based on the referenced Knowledge Base article:
// call in main() before printing to stdout
// returns TRUE if program is in its own console (cursor at 0,0) or
// FALSE if it was launched from an existing console.
// See http://support.microsoft.com/kb/99115
#include <stdio.h>
#include <windows.h>
int separate_console( void)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE), &csbi))
{
printf( "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
return FALSE;
}
// if cursor position is (0,0) then we were launched in a separate console
return ((!csbi.dwCursorPosition.X) && (!csbi.dwCursorPosition.Y));
}
GetConsoleTitle()
I've seen code which performs
if (!GetConsoleTitle(NULL, 0) && GetLastError() == ERROR_SUCCESS) {
// Console
} else {
// GUI
}
BUT... I've found that AttachConsole() is more helpful
In C++ (off the top of my head, and I'm no C++ programmer)
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
// GUI
} else {
// Console, and you have a handle to the console that already exists.
}
Is more effective. Additionally, if you find yourself in a GUI environment and would like to stay there as long as you can, but later find something catastrophic has happened that could really use a dump to a console window (you can't be arsed writing an edit box window to lot it to or attach to the NT System log and throw up a MessageBox()) well then you can AllocConsole() later on in the process, when GUI methods have failed.
I've found a much better solution using GetConsoleProcessList to get the attached process count to the current console.
If this process is the only one attached it will be closed when the process exists.
I found it in a post https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922
But it had a bug (at least in windows 10) since the documentation forbids invoking this function with null.
My solution was:
DWORD procId;
DWORD count = GetConsoleProcessList(&procId, 1);
if (count < 2) ...
I believe cmd.exe sets the CMDCMDLINE and CMDEXTVERSION environemntal variables when it starts. So if these are set your program was most probably started from a shell.
This isn't foolproof but it's something.
It's also possible to determine your parent PID in a few convoluted and possibly unreliable ways, or so I gather. You may want to look into that.
Here is the excellent answer from #DanielBenSassoon adapted for C#. Tested in Visual Studio 2019 and Windows 10.
// Gets a list of the process IDs attached to this console
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint GetConsoleProcessList(uint[] processList, uint processCount);
public static bool IsFinalProcess()
{
// See: https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922
uint[] procIDs = new uint[64];
uint processCount = GetConsoleProcessList(procIDs, 64);
return (processCount < 2);
}
This approach allows you to distinguish between four scenarios:
Debugging from the IDE (F5) [process count = 1]
Running from the IDE, but not debugging (Ctrl + F5) [process count = 2]
Double-clicking in Explorer [process count = 1]
Running from a command-prompt window [process count = 2]
When IsFinalProcess is true, you can use Console.ReadKey(false); to prevent the console window from disappearing after your application exits.
EDIT: I've been using this .bat/.cmd wrapper successfully for a couple of years now:
#ECHO OFF
REM Determine if script was executed from an interactive shell
(echo %CMDCMDLINE% | find /i "%~0" >NUL 2>&1) && (set IS_INTERACTIVE=false) || (set IS_INTERACTIVE=true)
<call console application here>
REM Wait for keystroke
if "%IS_INTERACTIVE%" == "false" (
echo.
echo Hit any key to close.
pause >NUL 2>&1
)
The advantage here is that this will work for all console applications, be it your own or someone else's (for which you might not have sources you could modify). The downside is, well, that you have a separate wrapper.
My original answer back in 2014 was this:
This works like a charm:
#echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" goto nonconsole
:console
<do something>
goto exit
:nonconsole
<do something>
pause
:exit
Copied from this thread. I also tried evaluating %cmdcmdline% myself, however there's an issue regarding quote characters ("), which prevents something like if "%cmdcmdline%" == "%ComSpec%" goto [target] from working.

Resources