Oct 29, 2007

Find Complete line NOT matched by the regular expression

Some times it’s required get all the instances which are not in the match string.
For example consider the following string.

I think that Michel Smith
is a fictional character. His real name
might be Michel Jackson, Michel Westling,
or Michel Liu for all we know.

If we are interested to get all lines which does not consist of word “Michel”, we can use Regex in .net and create a regular expression as follows

“^(?:(?!(.*Michel.*)).)*$\r?\n?”

i.e. ResultString = Regex.Match(strTest, "^(?:(?!Michel).)*$\r?\n?",RegexOptions.Multiline).Value

strTest contains the Test string.

and the job is done.

Happy coding…

Oct 3, 2007

TRY! MAGIC

#1 *An Indian discovered that nobody can create a FOLDER anywhere on the Computer which can be named as "CON". This is something pretty Cool...and Unbelievable. ... At Microsoft the whole Team, couldn't answer why this happened ! TRY IT NOW ,IT WILL NOT CREATE " CON " FOLDER **MAGIC

#2 * *For those of you using Windows, do the following: *1.) Open an empty notepad file 2.) Type "Bush hid the facts" (without the quotes) *3 *.) Save it as whatever you want. 4.) Close it, and re-open it. *MAGIC

#3 *Open Microsoft Word and type =rand (200, 99) And then press ENTER Then see the magic...

This can help to understand why

1.Device names such as COM1, CON or LPT1 are reserved words, and they can't be used as folder or file names.

2. The reasons why notepad is not able to display any combination of string if the text contains the words with 4 3 3 5 number of letters..
Finally found out that its not a bug with notepad..
What happens is..
Whenever we open a text file in notepad, it determines whether the text is ASCII or Unicode.. But actually there is no way in the world to exactly determine whether the text is ASCII or Unicode.. There is a function called IsTextUnicode in windows API.. The function does some tests on the text based on statistical data.. This is what MSDN says about the function.."The function uses various statistical and deterministic methods to make its determination.. These tests are not foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII strings can slip through. For example, if lpBuffer points to the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the IS_TEXT_UNICODE_STATISTICS test, though failure would be preferable."
And the book "Programming application for microsoft windows by Jeffrey Ritcher" says that this function does not give accurate results if the text is too small to do the tests..
If u open the file explicitly in ASCII mode in notepad, you can see the text correctly..
There can be only 2 reasons why notepad shows the file correctly through wine.. One is there may be no unicode support in wine.. or wine has a much better statistical and deterministic methods than microsoft to determine the text is ASCII or Unicode..
But the possibility of second is very remote.

test with typing these strings for your self...
aaaa aaa aaa aaaaa
hows are you mammu

3. When you need to type some text into a Word document for test purposes, don't waste your time--let Word do the job for you. Let's say that you would like to type in a single four-sentence paragraph. Just click at a blank line in your document, type =rand(1,4) and press Enter. Word will automatically type: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
The first number inside the parentheses is the number of paragraphs and the second number is the number of sentences in each paragraph. So, for 22 paragraphs of 22 sentences, you'd enter =rand(22,22).

Sep 26, 2007

Make your Life easy for Debugging KSH Shell Script

One of the problem that’s comes while debugging the KSH script is to use echo command to check the script health.

Well KSH Script debugging in not very easy, one may want to test the script in a test environment and before publishing the script need to remove or comment debugging lines from source code.

Following mechanism could make you life easy.

Use following lines at the beginning of the script:

if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi

Where ever you put a debugging line that is only for testing, use it in the following way:

DEBUG set –x

Or echo a parameter

DEBUG echo $PATH

Or set a parameter that is valid only during the test

DEBUG export LOGFILE=/tmp

Now the trick is before executing the script, set the DEBUG variable in the KSH shell as

# export DEBUG=yes

While the execution of the script, the DEBUG lines will be executed. Now when the script is published if you happen to forget deletion of the debuging lines; they shall never disturb the script execution.

Example
#!/usr/bin/ksh
#export DEBUG=yes # if u want to include debuging line

#export DEBUG="" # if u want to remove debuging line

if [[ -z $DEBUG ]];then
alias DEBUG='# '
else
alias DEBUG=''
fi

LOG_FILE=./out/script.out
DEBUG LOG_FILE=./out/script.out

function add {
a=$1 b=$2
return $((a + b))

}

# MAIN


DEBUG echo "test execution"
DEBUG echo "$(date) script execution" >>$LOG_FILEDEBUG


echo "if you do not know it:"

add 2 2echo " 2 + 2 = $?"

Make your life easy……

Sep 21, 2007

Input String Validation

What if your validation logic just requires allowing only alphanumeric string with some special characters

Lets say it must not allow any special characters except (dollar sign $, underscore _, hyphen - , asterisk* and question mark?)

There could be many ways to implement the logic, but I love to do it using regular expressions.

So just use RegEx ValidString = new RegEx("^[-_A-Za-z0-9\?\*\*]$"); to verify the input is a valid string.

Ok job done, but what if you needs to identify the invalid character in user input.
The trick could be too just use the negative of above Regex.

RegEx InValidSplCharacter = new RegEx("[^-_A-Za-z0-9\?\*\*]");

So small way to do big things, this is what I love about Regular expression.

Sep 18, 2007

Process performance counter is disabled" exception on Process.GetProcessesByName ( )

TheLearnedOne:Here's another possibility:

http://forums.grouper.com/archive/index.php/t-134.html

Extract:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q248993

Even if you use the below procedure you shall get the same error. try it for your own.

Reenabling an Extension by Using Regedit.exe
WARNING: If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from using Registry Editor incorrectly. Use Registry Editor at your own risk.

Start Regedit.exe. (You cannot use Regedt32.exe because it does not allow searching for registry values.)
Click to select the following key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

Select Find from the Edit menu.
In the Find What field, type Disable Performance Counters.
Click Find Next. This will locate a Performance key that may have this Registry value set to 1.
If the Registry value is set to 1, set the value to 0 or delete the Registry value.
Press F3 to find the next occurrence of this Registry value.
Repeat the previous two steps until there are no Performance keys that have the Disable Performance Counters value set to 1.
NOTE: Often the "Disable Performance Counters" value does not appear in the registry. The value can be created and given a DWORD value of 1 to disable counters.


refer to this Microsoft article

http://support.microsoft.com/default.aspx?kbid=300956

Basically after Latest SP2 Service Pack Update - the files perfc009.dat and perfh009.dat become corrupted.

http://support.microsoft.com/default.aspx?scid=kb;EN-US;314958

make backups of the two files in \windows\system32 with a .bak extension just in case you need them later...

Here are the 2 files put into the \Windows\System32 folder and see your application running.

perfc009.dat (http://www.calforums.com/perfc009.dat)
perfh009.dat (http://www.calforums.com/perfh009.dat)


source: http://www.experts-exchange.com/Programming/Languages/.NET/Q_21285890.html

Working with the System.Diagnostic.Process Class


Working with the System.Diagnostic.Process Class

Introduction

The System.Diagnostic.Process class is used for the starting and stopping of processes; and controlling and monitoring application. With this powerful class you can gain access to information and use it to create an instance of an application or stop a running process. This FAQ will cover how to get a list of running process and how to start a new process by calling an executable or a register file extension (like .doc).



Why would you want to use the Process class? This class is the "Successor" to the Shell command in VB6. If you need to start an application with parameters, or get notified when it exits, this class provides the power and information you need.



Note: All code provide assumes that you have the Imported the System.Diagnostics namespace. The simplest way to do this is to add the following line of code at the top of your file. Also, for the code posted in this FAQ output is dumped to the Output window using the Debug.WriteLine method.


Code:
Imports System.Diagnostics


Getting Information

Getting information from the current process.

It's important to find out what information we can obtain from a Process, so let's take a look at the information available. This example will be using the GetCurrentProcess to retrieve a reference to the applications process component. To do this we will declare a variable and use the shared GetCurrentProcess method to retrieve the object reference. All further code in the section will build on this declaration.


Code:
Dim proc As Process = Process.GetCurrentProcess


Now that we have a reference to our Process, let's find out what information it can tell us. There is a lot of information you can retrieve from a Process Object. Here are just a few of them.


Code:
' Unique identifier for this process.

Debug.WriteLine(proc.Id.ToString)

' Name of the process.

Debug.WriteLine(proc.ProcessName)

' This process's native handle.

Debug.WriteLine(proc.Handle.ToString)

' Caption of the main window.

Debug.WriteLine(proc.MainWindowTitle)

' Window handle of the main window

Debug.WriteLine(proc.MainWindowHandle)

' Base Priority Information.

Debug.WriteLine(proc.BasePriority.ToString)

' Overall priority category

Debug.WriteLine(proc.PriorityClass.ToString)

' Number of handles this process has opened.

Debug.WriteLine(proc.HandleCount.ToString)

' Indicates whether the user interface of this process is responding.

Debug.WriteLine(proc.Responding.ToString)



There are more properties available including information on Processor and Memory usage.



Getting a list of the Current Processes

Getting a list of the current processes running on your system is an easy task. We can use the shared method GetProcesses() to retrieve this information. The GetProcesses() method returns an Array of Process components that we can further query to learn more about any given process.


Code:
' Declare a Process class.

Dim proc As Process

' Loop through the Processes and write the name of the Process to the output window.

For each proc In Process.GetProcesses

Debug.Writeline(proc.ProcessName)

Next


Starting a Process

Starting a Process with the Shared Start method.

Starting a Process is a manner of knowing what the path to the executable (or other object that can be started through the run command). The simplest way to do this is to use the Shared Start method of the Process class. This example will be using notepad.exe and a text file named info.txt.


Code:
' Start an instance of Notepad.

Process.Start("notepad.exe")

' Start an instance of Notepad and open the info.txt file.

Process.Start("notepad.exe", "c:\info.txt")

' Start an instance of the application that is registered to txt files.

' Just like you would double-click a file in Windows Explorer.

Process.Start("c:\info.txt")


On most systems, the "txt" extension is registered to the Notepad application. This will start a new instance of Notepad and open the info.txt file.



These shared methods offer a way to create a process, but if we need more control over the process we need to create an instance of the Process class itself and use the StartInfo object. Also the shared method will throw an error if we pass a file that is not registered with the system.



Starting a Process using the Process Class and the StartInfo object.

Starting a process using the StartInfo object is relatively easy. The only required property is StartInfo.FileName which is a string specifying what to start. So why would you use it. Simple, you can provide error handling if a file is not registered and specify the WindowStyle. Also creating an instance of the Process Class allows for notification when the process has exited through events. Below we will start notepad again and pass it the argument of "C:\info.txt"


Code:
' Create an Instance of the Process Class

Dim proc As New Process

' Provide the name of the application or file.

proc.StartInfo.FileName = "notepad.exe"

' Specify the arguments.

proc.StartInfo.Arguments = "c:\info.txt"

' Start the process.

proc.Start


Simple, right? Good.



Using Events to find out when a process has Exited.

The process class exposes two events; Disposed and Exited. Disposed is inherited from Component, Exited occurs when the process exits. First we need to create an event handler that will execute when the process exits. In our event handler, we will write the ExitCode and ExitTime properties to the output window.


Code:
Private Sub OnProcessExit(ByVal sender As Object, ByVal e As EventArgs)

' Avoid late binding and Cast the Object to a Process.

Dim proc As Process = CType(sender, Process)

' Write the ExitCode

Debug.WriteLine(proc.ExitCode)

' Write the ExitTime

Debug.WriteLine(proc.ExitTime.ToString)

End Sub


So now we have an event handler, but how do we get the event handler to fire? To do this we must add two lines of code before we start our process. We need to set EnableRaisingEvents to True in order for the events to fire. We must also add an event handler to trap the Exited event and run our OnProcessExit method.


Code:
Dim proc As New Process

' Provide the name of the application or file.

proc.StartInfo.FileName = "notepad.exe"

' Specify the arguments.

proc.StartInfo.Arguments = "c:\info.txt"

' This will allow the Exited event to fire.

proc.EnableRaisingEvents = True

' Add an event handler for this process.

' Run the OnProcessExit sub when this process exits.

AddHandler proc.Exited, AddressOf OnProcessExit

' Start the process.

proc.Start()


Now when the process exits, the Exited Event will be raised and our OnProcessExit method will be called.



Providing Error Handling

Providing error handling is a crucial part of any application. With the process method you will want to catch any error that is raised. The most common error is a file not found, the second most common error is dealing with files that are not registered to any particular application.



You can proactively avoid "file not found" errors by using the Shared Exists method of the System.IO.File class. We will use this later when we put everything together to create our StartProcess Method.


Code:
If System.IO.File.Exists(path) = False Then

Exit Sub

End If


Dealing with files that are not registered in the system is a little different. When you use Windows Explorer and try to open a file that is not registered, you are prompted with the "Open With" dialog and can then choose the application to open the file with. This functionality is provided by the Process class by setting the ErrorDialog Property in the StartInfo object to True.


Code:
proc.StartInfo.ErrorDialog = True


Putting it all together

Now that we have an understanding of the Process component and some of the things we can do, I am going to share two methods that I use for starting a Process.


Code:
' Method to Start a Process with Error Handling.

Private Sub StartProcess(ByVal Path As String)

' Declare the Process variable.

Dim proc As Process

' Ensure that the file exists

If System.IO.File.Exists(Path) = False Then

Exit Sub

End If

' Create the Process component.

proc = New Process

' Set EnableRaisingEvents to True.

proc.EnableRaisingEvents = True

' Add an event handler to trap the Exited event.

AddHandler proc.Exited, AddressOf OnProcessExit

' Build the StartInfo object.

' Set the FileName property to the argument that was passed.

proc.StartInfo.FileName = Path

' Enable the ErrorDialog.

proc.StartInfo.ErrorDialog = True

' Start the Process

proc.Start()

End Sub



' Event Handler for Process.Exited Event

Private Sub OnProcessExit(ByVal sender As Object, ByVal e As EventArgs)

' Avoid late binding and cast the Object to a specific Process component.

Dim proc As Process = CType(sender, Process)

' Write out the Exit information.

Debug.WriteLine(proc.ExitCode)

Debug.WriteLine(proc.ExitTime)

' Dispose and Clear the object.

proc.Dispose()

proc = Nothing

End Sub







source: http://vbcity.com/forums/topic.asp?tid=29605


Jul 9, 2007

With VB.NET, there is no TextWidth method of Object like we have in VB.

TextWidth : Returns the width of a text string as it would be printed in the current font of a Form, PictureBox, or Printer.


Syntax in VB


object.TextWidth(string)


The TextWidth method syntax has these parts:

object Optional. An object expression that evaluates to an object in the Applies To list. If object is omitted, the Form with the focus is assumed to be object.


String Required. A string expression that evaluates to a string for which the text width is determined. Parentheses must surround the string expression.



Remarks


The width is expressed in terms of the ScaleMode property setting or Scale method coordinate system in effect for object. Use TextWidth to determine the amount of horizontal space required to display the text. If string contains embedded carriage returns, TextWidth returns the width of the longest line.

So What do in VB.NET ?


Well there is a way. Suppose we need to acquire the width of text in a TextBox as TextBox1
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics

MsgBox(myGraphics.MeasureString(TextBox1.Text, Me.Font).Width)


This Could be very helpful in MSFlex Grid

You need to Resize Column Width of MSFlexGrid depending upon the Maximum Text width

Private Sub SizeColumns()
Dim g As Graphics = Me.CreateGraphics()
Dim myGraphics As System.Drawing.Graphics
myGraphics = Me.CreateGraphics
Dim FlexWidth2Trans As Integer
FlexWidth2Trans = (1440 / g.DpiX)

NOTE: MSFlexGrid uses twips, but .NET uses pixels. So by multiplying the inches by 1440, the twips to pixel conversion now gives the same result as in the original

Dim row_num As Integer
Dim col_num As Integer
Dim max_width As Single

For col_num = 0 To AxMSFlexGrid1.Cols - 1
max_width = 0
For row_num = 0 To AxMSFlexGrid1.Rows - 1
If max_width < myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width Then max_width = myGraphics.MeasureString(AxMSFlexGrid1.get_TextMatrix(row_num, col_num), Me.Font).Width * FlexWidth2Trans End If Next row_num AxMSFlexGrid1.set_ColWidth(col_num, max_width + 240) Next col_num End Sub

Jul 4, 2007

How to spawn console processes with redirected standard handles

This article describes how to redirect the input and output of a child process that receives input from the standard input handle or sends output to the standard output handle. The Win32 API enables applications to spawn a child console process with redirected standard handles. This feature allows a parent process to send and receive the input and output of the child process.

Note Some console based applications do not use the standard handles for their input/output (IO) operations. The Win32 API does not support redirection of these processes.

The CreateProcess() API through the STARTUPINFO structure enables you to redirect the standard handles of a child console based process. If the dwFlags member is set to STARTF_USESTDHANDLES, then the following STARTUPINFO members specify the standard handles of the child console based process: HANDLE hStdInput - Standard input handle of the child process.

HANDLE hStdOutput - Standard output handle of the child process.
HANDLE hStdError - Standard error handle of the child process.

You can set these handles to either a pipe handle, file handle, or any handle that can do synchronous reads and writes through the ReadFile() and WriteFile() API. The handles must be inheritable and the CreateProcess() API must specify that inheritable handles are to be inherited by the child process by specifying TRUE in the bInheritHandles parameter. If the parent process only wishes to redirect one or two standard handles, specifying GetStdHandle() for the specific handles causes the child to create the standard handle as it normally would without redirection. For example, if the parent process only needs to redirect the standard output and error of the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows: hStdInput = GetStdHandle(STD_INPUT_HANDLE);


Note Child processes that use such C run-time functions as printf() and fprintf() can behave poorly when redirected. The C run-time functions maintain separate IO buffers. When redirected, these buffers might not be flushed immediately after each IO call. As a result, the output to the redirection pipe of a printf() call or the input from a getch() call is not flushed immediately and delays, sometimes-infinite delays occur. This problem is avoided if the child process flushes the IO buffers after each call to a C run-time IO function. Only the child process can flush its C run-time IO buffers. A process can flush its C run-time IO buffers by calling the fflush() function.

Note Windows 95 and Windows 98 require an extra step when you redirect the standard handles of certain child processes.

The following sample redirects the standard input, output, and error of the child process specified in the CreateProcess call. This sample redirects the provided console process (Child.c).


Sample code
/*++
Copyright (c) 1998 Microsoft Corporation

Module Name:

Redirect.c

Description:

This sample illustrates how to spawn a child console based
application with redirected standard handles.

The following import libraries are required:
user32.lib

Dave McPherson (davemm) 11-March-98
--*/


#include
#pragma comment(lib, "User32.lib")
void DisplayError(char *pszAPI);
void ReadAndHandleOutput(HANDLE hPipeRead);
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr);
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam);
HANDLE hChildProcess = NULL;
HANDLE hStdIn = NULL; // Handle to parents std input.
BOOL bRunThread = TRUE;
void main ()
{
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
HANDLE hInputWriteTmp,hInputRead,hInputWrite;
HANDLE hErrorWrite;
HANDLE hThread;
DWORD ThreadId;
SECURITY_ATTRIBUTES sa;

// Set up the security attributes struct.
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

// Create the child output pipe.

if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
DisplayError("CreatePipe");
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
DisplayError("DuplicateHandle");

// Create the child input pipe.
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
DisplayError("CreatePipe");
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");

// Close inheritable copies of the handles you do not want to be
// inherited.
if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");

// Get std input handle so you can close it and force the ReadFile to
// fail when you want the input thread to exit.
if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
INVALID_HANDLE_VALUE )
DisplayError("GetStdHandle");

PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);

// Close pipe handles (do not continue to modify the parent).
// You need to make sure that no handles to the write end of the
// output pipe are maintained in this process or else the pipe will
// not close when the child process exits and the ReadFile will hang.
if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");

// Launch the thread that gets the input and sends it to the child.
hThread = CreateThread(NULL,0,GetAndSendInputThread,
(LPVOID)hInputWrite,0,&ThreadId);
if (hThread == NULL) DisplayError("CreateThread");

// Read the child's output.
ReadAndHandleOutput(hOutputRead);
// Redirection is complete

// Force the read on the input to return by closing the stdin handle.
if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");

// Tell the thread to exit and wait for thread to die.
bRunThread = FALSE;
if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
DisplayError("WaitForSingleObject");
if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
}

///////////////////////////////////////////////////////////////////////

// PrepAndLaunchRedirectedChild
// Sets up STARTUPINFO structure, and launches redirected child.
///////////////////////////////////////////////////////////////////////
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
HANDLE hChildStdIn,
HANDLE hChildStdErr)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
// Set up the start up info struct.
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hChildStdOut;
si.hStdInput = hChildStdIn;
si.hStdError = hChildStdErr;
// Use this if you want to hide the child:
// si.wShowWindow = SW_HIDE;
// Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
// use the wShowWindow flags.
// Launch the process that you want to redirect (in this case,
// Child.exe). Make sure Child.exe is in the same directory as
// redirect.c launch redirect from a command line to prevent location
// confusion.
if (!CreateProcess(NULL,"Child.EXE",NULL,NULL,TRUE,
CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
DisplayError("CreateProcess");

// Set global child process handle to cause threads to exit.
hChildProcess = pi.hProcess;


// Close any unnecessary handles.
if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
}

///////////////////////////////////////////////////////////////////////
// ReadAndHandleOutput
// Monitors handle for input. Exits when child exits or pipe breaks.
///////////////////////////////////////////////////////////////////////
void ReadAndHandleOutput(HANDLE hPipeRead)
{
CHAR lpBuffer[256];
DWORD nBytesRead;
DWORD nCharsWritten;

while(TRUE)
{
if (!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
DisplayError("ReadFile"); // Something bad happened.
}

// Display the character read on the screen.
if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),lpBuffer,
nBytesRead,&nCharsWritten,NULL))
DisplayError("WriteConsole");
}
}


///////////////////////////////////////////////////////////////////////
// GetAndSendInputThread
// Thread procedure that monitors the console for input and sends input
// to the child process through the input pipe.
// This thread ends when the child application exits.
///////////////////////////////////////////////////////////////////////

DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
{
CHAR read_buff[256];
DWORD nBytesRead,nBytesWrote;
HANDLE hPipeWrite = (HANDLE)lpvThreadParam;

// Get input from our console and send it to child through the pipe.
while (bRunThread)
{
if(!ReadConsole(hStdIn,read_buff,1,&nBytesRead,NULL))
DisplayError("ReadConsole");
read_buff[nBytesRead] = '\0'; // Follow input with a NULL.
if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&nBytesWrote,NULL))
{
if (GetLastError() == ERROR_NO_DATA)
break; // Pipe was closed (normal exit path).
else
DisplayError("WriteFile");
}
}
return 1;
}


///////////////////////////////////////////////////////////////////////
// DisplayError
// Displays the error number and corresponding message.
///////////////////////////////////////////////////////////////////////

void DisplayError(char *pszAPI)
{
LPVOID lpvMessageBuffer;
CHAR szPrintBuffer[512];
DWORD nCharsWritten;

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
wsprintf(szPrintBuffer,
"ERROR: API = %s.\n error code = %d.\n message = %s.\n",
pszAPI, GetLastError(), (char *)lpvMessageBuffer);

WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),szPrintBuffer,
lstrlen(szPrintBuffer),&nCharsWritten,NULL);

LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}



//////////////////////////////////////////////////////////////////////
// child.c
// Echoes all input to stdout. This will be redirected by the redirect
// sample. Compile and build child.c as a Win32 Console application and
// put it in the same directory as the redirect sample.
//

#include
#include
#include
void main ()
{
FILE* fp;
CHAR szInput[1024];

// Open the console. By doing this, you can send output directly to
// the console that will not be redirected.

fp = fopen("CON", "w");
if (!fp) {
printf("Error opening child console - perhaps there is none.\n");
fflush(NULL);
}
else
{

// Write a message direct to the console (will not be redirected).

fprintf(fp,"This data is being printed directly to the\n");
fprintf(fp,"console and will not be redirected.\n\n");
fprintf(fp,"Since the standard input and output have been\n");
fprintf(fp,"redirected data sent to and from those handles\n");
fprintf(fp,"will be redirected.\n\n");
fprintf(fp,"To send data to the std input of this process.\n");
fprintf(fp,"Click on the console window of the parent process\n");
fprintf(fp,"(redirect), and enter data from it's console\n\n");
fprintf(fp,"To exit this process send the string 'exit' to\n");
fprintf(fp,"it's standard input\n");
fflush(fp);
}



ZeroMemory(szInput,1024);
while (TRUE)
{
gets(szInput);
printf("Child echoing [%s]\n",szInput);
fflush(NULL); // Must flush output buffers or else redirection
// will be problematic.
if (!_stricmp(szInput,"Exit") )
break;
ZeroMemory(szInput,strlen(szInput) );
}
}

Jul 3, 2007

Various methods for launching another program from one program VC++

There are several methods for launching another program from one program.

You can use _spawn(), _exec(), system(), WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess().



The system() function is a more portable function.

WinExec(), ShellExecute(), ShellExecuteEx(), and CreateProcess() are unique to Windows programming. All four windows functions allow for launching an application in the background (window-hidden).



The WinExec() is the easiest of the four to use. It only takes two arguments, however MS recommends using the CreateProcess() instead of WinExec on all 32-bit programs.



The ShellExecute() is easier to setup then CreateProcess, and it has more options then WinExec. However, it's also a legacy function. MS recommends using ShellExecuteEx() for Win32 applications.

HINSTANCE ShellExecute(

HWND hwnd,

LPCTSTR lpVerb,

LPCTSTR lpFile,

LPCTSTR lpParameters,

LPCTSTR lpDirectory,

INT nShowCmd

);



The ShellExecuteEx() only takes one parameter, but the parameter is a structure with many members, and it's almost as compicate as the CreateProcess() function.

BOOL ShellExecuteEx(

LPSHELLEXECUTEINFO lpExecInfo

);





The CreateProcess() function takes 10 parameters, and can be tricky to use.

int system( const char *command );

UINT WinExec(

LPCSTR lpCmdLine, // address of command line

UINT uCmdShow // window style for new application

);

BOOL CreateProcess(

LPCTSTR lpApplicationName,

// pointer to name of executable module

LPTSTR lpCommandLine, // pointer to command line string

LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes

LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes

BOOL bInheritHandles, // handle inheritance flag

DWORD dwCreationFlags, // creation flags

LPVOID lpEnvironment, // pointer to new environment block

LPCTSTR lpCurrentDirectory, // pointer to current directory name

LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO

LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION

);

How to convert Twips to Pixels and back again

Description: Visual Basic uses Twips by default instead of pixels, this shows how to convert between them
Its very easy to convert between Twips and Pixels, using the Screen object.

Heres how to convert from Twips to Pixels for Horizontal (X axis) positions:

CODE: Pixels = Twips / Screen.TwipsPerPixelX


And for Vertical (Y axis) positions:

CODE: Pixels = Twips / Screen.TwipsPerPixelY



To convert back again, just use (for horizontal):

CODE: Twips = Pixels * Screen.TwipsPerPixelX

And for vertical:

CODE: Twips = Pixels * Screen.TwipsPerPixelY


On most systems you can use either horizontal or vertical but I presume in some cases you can't, so its best to use the correct ones.


MSFlexGrid uses twips, but .NET uses pixels. You can use the code below to
convert pixels to twips:


Private m_TwipsPerPixelX As Integer
Private m_TwipsPerPixelY As Integer
....
Using g As Graphics = Me.CreateGraphics()
m_TwipsPerPixelX = 1440 / g.DpiX
m_TwipsPerPixelY = 1440 / g.DpiY
End Using
....
Me.MSFlexGrid1.ColWidth = 100 * m_TwipsPerPixelX