|
(I don't feel that this code is enough to warrant a full article.)
Many times when writing a command-line/console application or utility, I desire different behavior when the input is a pipe or the output is redirected. For instance:
0) I may not be able to prompt for input or confirmation.
1) I may want to make the output more (or less) verbose.
It appears that .net does not make detecting such redirection easy. When I first butted up against this wall I searched and found an article by Dr. Gui which addressed using the Windows API function PeekConsoleInput to detect whether or not console input is a pipe. More recent searches have not turned up this article or any other.
Here then is my take on Dr. Gui's technique, with the ability to detect redirected output added:
# region Heading
/**************************************************************************************************************/
/* */
/* LibApi.IsPipe.cs */
/* */
/* IsPipe routine */
/* */
/* This is free code, use it as you require. If you modify it please use your own namespace. */
/* */
/* If you like it or have suggestions for improvements please let me know at: PIEBALDconsult@aol.com */
/* */
/* Modification history: */
/* 2003-11-24 Sir John E. Boucher Added IsPipe -- With thanks to Dr. Gui */
/* */
/**************************************************************************************************************/
# endregion
namespace PIEBALD.Lib
{
public static partial class LibApi
{
/**
<summary>
Standard I/O device numbers
</summary>
*/
public enum StdPort : uint
{
/**
<summary>
Standard input port
</summary>
*/
In = unchecked ( (uint) -10 )
,
/**
<summary>
Standard output port
</summary>
*/
Out = unchecked ( (uint) -11 )
,
/**
<summary>
Standard error port
</summary>
*/
Err = unchecked ( (uint) -12 )
} ;
/**************************************************************************************************************/
[System.Runtime.InteropServices.DllImportAttribute
(
"Kernel32"
,
SetLastError=true
,
EntryPoint="GetStdHandle"
)]
private static extern System.IntPtr
API_GetStdHandle
(
StdPort nStdHandle
) ;
[System.Runtime.InteropServices.DllImportAttribute
(
"Kernel32"
,
SetLastError=true
,
EntryPoint="PeekConsoleInput"
)]
private static extern bool
API_PeekConsoleInput
(
System.IntPtr hConsoleInput
,
System.IntPtr lpBuffer
,
uint nLength
,
out uint lpNumberOfEventsRead
) ;
[System.Runtime.InteropServices.DllImportAttribute
(
"Kernel32"
,
SetLastError=true
,
EntryPoint="WriteConsole"
)]
private static extern bool
API_WriteConsole
(
System.IntPtr hConsoleOutput
,
System.IntPtr lpBuffer
,
uint nNumberOfCharsToWrite
,
out uint lpNumberOfCharsWritten
,
System.IntPtr lpReserved
) ;
/**
<summary>
Test a standard I/O (console) port to determine whether or not it is a pipe (redirected)
</summary>
<remarks>
From a post by Dr. Gui
</remarks>
<param name="Port">
The port to test for pipeness
</param>
<returns>
Whether or not the port appears to be a pipe
</returns>
*/
public static bool
IsPipe
(
StdPort Port
)
{
bool result = false ;
uint junk ;
switch ( Port )
{
case StdPort.In :
{
result = !API_PeekConsoleInput
(
API_GetStdHandle ( Port )
,
System.IntPtr.Zero
,
0
,
out junk
) ;
break ;
}
case StdPort.Out :
case StdPort.Err :
{
result = !API_WriteConsole
(
API_GetStdHandle ( Port )
,
System.IntPtr.Zero
,
0
,
out junk
,
System.IntPtr.Zero
) ;
break ;
}
}
return ( result ) ;
}
/**************************************************************************************************************/
}
}
|
|
|
|