Vanara/PInvoke/Kernel32/ProcessEnv.cs

370 lines
21 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
/// <summary>Standard device handle types used by <see cref="GetStdHandle"/>.</summary>
[PInvokeData("Winbase.h")]
public enum StdHandleType : int
{
/// <summary>The standard input device. Initially, this is the console input buffer, CONIN$.</summary>
STD_INPUT_HANDLE = -10,
/// <summary>The standard output device. Initially, this is the active console screen buffer, CONOUT$.</summary>
STD_OUTPUT_HANDLE = -11,
/// <summary>The standard error device. Initially, this is the active console screen buffer, CONOUT$.</summary>
STD_ERROR_HANDLE = -12,
}
/// <summary>
/// <para>Expands environment-variable strings and replaces them with the values defined for the current user.</para>
/// <para>To specify the environment block for a particular user or the system, use the <c>ExpandEnvironmentStringsForUser</c> function.</para>
/// </summary>
/// <param name="lpSrc">
/// <para>
/// A buffer that contains one or more environment-variable strings in the form: %variableName%. For each such reference, the
/// %variableName% portion is replaced with the current value of that environment variable.
/// </para>
/// <para>
/// Case is ignored when looking up the environment-variable name. If the name is not found, the %variableName% portion is left unexpanded.
/// </para>
/// <para>
/// Note that this function does not support all the features that Cmd.exe supports. For example, it does not support
/// %variableName:str1=str2% or %variableName:~offset,length%.
/// </para>
/// </param>
/// <param name="lpDst">
/// A pointer to a buffer that receives the result of expanding the environment variable strings in the lpSrc buffer. Note that this
/// buffer cannot be the same as the lpSrc buffer.
/// </param>
/// <param name="nSize">
/// The maximum number of characters that can be stored in the buffer pointed to by the lpDst parameter. When using ANSI strings, the
/// buffer size should be the string length, plus terminating null character, plus one. When using Unicode strings, the buffer size
/// should be the string length plus the terminating null character.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is the number of <c>TCHARs</c> stored in the destination buffer, including the
/// terminating null character. If the destination buffer is too small to hold the expanded string, the return value is the required
/// buffer size, in characters.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// DWORD WINAPI ExpandEnvironmentStrings( _In_ LPCTSTR lpSrc, _Out_opt_ LPTSTR lpDst, _In_ DWORD nSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724265")]
public static extern uint ExpandEnvironmentStrings(string lpSrc, StringBuilder lpDst, uint nSize);
/// <summary>Frees a block of environment strings.</summary>
/// <param name="lpszEnvironmentBlock">
/// A pointer to a block of environment strings. The pointer to the block must be obtained by calling the
/// <c>GetEnvironmentStrings</c> function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI FreeEnvironmentStrings( _In_ LPTCH lpszEnvironmentBlock); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683151(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683151")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeEnvironmentStrings(IntPtr lpszEnvironmentBlock);
/// <summary>Retrieves the command-line string for the current process.</summary>
/// <returns>The return value is a pointer to the command-line string for the current process.</returns>
// LPTSTR WINAPI GetCommandLine(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms683156")]
public static string GetCommandLine() => Marshal.PtrToStringAuto(GetCommandLineInternal());
/// <summary>Retrieves the current directory for the current process.</summary>
/// <param name="nBufferLength">
/// The length of the buffer for the current directory string, in <c>TCHARs</c>. The buffer length must include room for a
/// terminating null character.
/// </param>
/// <param name="lpBuffer">
/// <para>
/// A pointer to the buffer that receives the current directory string. This null-terminated string specifies the absolute path to
/// the current directory.
/// </para>
/// <para>To determine the required buffer size, set this parameter to <c>NULL</c> and the nBufferLength parameter to 0.</para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the
/// terminating null character.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// If the buffer that is pointed to by lpBuffer is not large enough, the return value specifies the required size of the buffer, in
/// characters, including the null-terminating character.
/// </para>
/// </returns>
// DWORD WINAPI GetCurrentDirectory( _In_ DWORD nBufferLength, _Out_ LPTSTR lpBuffer); https://msdn.microsoft.com/en-us/library/windows/desktop/aa364934(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "aa364934")]
public static extern uint GetCurrentDirectory(uint nBufferLength, StringBuilder lpBuffer);
/// <summary>Retrieves the environment variables for the current process.</summary>
/// <returns>
/// <para>If the function succeeds, the return value is a pointer to the environment block of the current process.</para>
/// <para>If the function fails, the return value is NULL.</para>
/// </returns>
// LPTCH WINAPI GetEnvironmentStrings(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms683187")]
public static string[] GetEnvironmentStrings()
{
var ptr = InternalGetEnvironmentStrings();
try { return ptr.ToStringEnum().ToArray(); }
finally { FreeEnvironmentStrings(ptr); }
}
/// <summary>Retrieves the contents of the specified variable from the environment block of the calling process.</summary>
/// <param name="lpName">The name of the environment variable.</param>
/// <param name="lpBuffer">
/// A pointer to a buffer that receives the contents of the specified environment variable as a null-terminated string. An
/// environment variable has a maximum size limit of 32,767 characters, including the null-terminating character.
/// </param>
/// <param name="nSize">
/// The size of the buffer pointed to by the lpBuffer parameter, including the null-terminating character, in characters.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer, not including
/// the terminating null character.
/// </para>
/// <para>
/// If lpBuffer is not large enough to hold the data, the return value is the buffer size, in characters, required to hold the string
/// and its terminating null character and the contents of lpBuffer are undefined.
/// </para>
/// <para>
/// If the function fails, the return value is zero. If the specified environment variable was not found in the environment block,
/// <c>GetLastError</c> returns ERROR_ENVVAR_NOT_FOUND.
/// </para>
/// </returns>
// DWORD WINAPI GetEnvironmentVariable( _In_opt_ LPCTSTR lpName, _Out_opt_ LPTSTR lpBuffer, _In_ DWORD nSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683188")]
public static extern uint GetEnvironmentVariable(string lpName, StringBuilder lpBuffer, uint nSize);
/// <summary>Retrieves a handle to the specified standard device (standard input, standard output, or standard error).</summary>
/// <param name="nStdHandle">
/// <para>The standard device. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>STD_INPUT_HANDLE (DWORD)-10</term>
/// <term>The standard input device. Initially, this is the console input buffer, CONIN$.</term>
/// </item>
/// <item>
/// <term>STD_OUTPUT_HANDLE (DWORD)-11</term>
/// <term>The standard output device. Initially, this is the active console screen buffer, CONOUT$.</term>
/// </item>
/// <item>
/// <term>STD_ERROR_HANDLE (DWORD)-12</term>
/// <term>The standard error device. Initially, this is the active console screen buffer, CONOUT$.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is a handle to the specified device, or a redirected handle set by a previous call to
/// <c>SetStdHandle</c>. The handle has <c>GENERIC_READ</c> and <c>GENERIC_WRITE</c> access rights, unless the application has used
/// <c>SetStdHandle</c> to set a standard handle with lesser access.
/// </para>
/// <para>If the function fails, the return value is <c>INVALID_HANDLE_VALUE</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// If an application does not have associated standard handles, such as a service running on an interactive desktop, and has not
/// redirected them, the return value is <c>NULL</c>.
/// </para>
/// </returns>
// HANDLE WINAPI GetStdHandle( _In_ DWORD nStdHandle ); https://docs.microsoft.com/en-us/windows/console/getstdhandle
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h")]
public static extern HFILE GetStdHandle(StdHandleType nStdHandle);
/// <summary>Determines whether the current directory should be included in the search path for the specified executable.</summary>
/// <param name="ExeName">The name of the executable file.</param>
/// <returns>
/// If the current directory should be part of the search path, the return value is TRUE. Otherwise, the return value is FALSE.
/// </returns>
// BOOL WINAPI NeedCurrentDirectoryForExePath( _In_ LPCTSTR ExeName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684269(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms684269")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool NeedCurrentDirectoryForExePath(string ExeName);
/// <summary>Searches for a specified file in a specified path.</summary>
/// <param name="lpPath">
/// <para>The path to be searched for the file.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the function searches for a matching file using a registry-dependent system search path. For
/// more information, see the Remarks section.
/// </para>
/// </param>
/// <param name="lpFileName">The name of the file for which to search.</param>
/// <param name="lpExtension">
/// <para>
/// The extension to be added to the file name when searching for the file. The first character of the file name extension must be a
/// period (.). The extension is added only if the specified file name does not end with an extension.
/// </para>
/// <para>If a file name extension is not required or if the file name contains an extension, this parameter can be <c>NULL</c>.</para>
/// </param>
/// <param name="nBufferLength">
/// The size of the buffer that receives the valid path and file name (including the terminating null character), in <c>TCHARs</c>.
/// </param>
/// <param name="lpBuffer">
/// A pointer to the buffer to receive the path and file name of the file found. The string is a null-terminated string.
/// </param>
/// <param name="lpFilePart">
/// A pointer to the variable to receive the address (within lpBuffer) of the last component of the valid path and file name, which
/// is the address of the character immediately following the final backslash (\) in the path.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the value returned is the length, in <c>TCHARs</c>, of the string that is copied to the buffer, not
/// including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of
/// the buffer that is required to hold the path, including the terminating null character.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// DWORD WINAPI SearchPath( _In_opt_ LPCTSTR lpPath, _In_ LPCTSTR lpFileName, _In_opt_ LPCTSTR lpExtension, _In_ DWORD nBufferLength,
// _Out_ LPTSTR lpBuffer, _Out_opt_ LPTSTR *lpFilePart); https://msdn.microsoft.com/en-us/library/windows/desktop/aa365527(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "aa365527")]
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint SearchPath([In, Optional] string lpPath, string lpFileName, [In, Optional] string lpExtension, uint nBufferLength, StringBuilder lpBuffer, out IntPtr lpFilePart);
/// <summary>Changes the current directory for the current process.</summary>
/// <param name="lpPathName">
/// <para>
/// The path to the new current directory. This parameter may specify a relative path or a full path. In either case, the full path
/// of the specified directory is calculated and stored as the current directory. For more information, see File Names, Paths, and Namespaces.
/// </para>
/// <para>
/// In the ANSI version of this function, the name is limited to <c>MAX_PATH</c> characters. To extend this limit to 32,767 wide
/// characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File.
/// </para>
/// <para>
/// The final character before the null character must be a backslash ('\'). If you do not specify the backslash, it will be added
/// for you; therefore, specify <c>MAX_PATH</c>-2 characters for the path unless you include the trailing backslash, in which case,
/// specify <c>MAX_PATH</c>-1 characters for the path.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetCurrentDirectory( _In_ LPCTSTR lpPathName); https://msdn.microsoft.com/en-us/library/windows/desktop/aa365530(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "aa365530")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCurrentDirectory(string lpPathName);
/// <summary>Sets the environment strings.</summary>
/// <param name="NewEnvironment">
/// The new environment strings. List of unicode null terminated strings with a double null termination at the end.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
[PInvokeData("ProcessEnv.h", MSDNShortId = "")]
[DllImport(Lib.Kernel32, SetLastError = true, EntryPoint = "SetEnvironmentStringsW", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetEnvironmentStrings([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Unicode")] string[] NewEnvironment);
/// <summary>Sets the contents of the specified environment variable for the current process.</summary>
/// <param name="lpName">
/// The name of the environment variable. The operating system creates the environment variable if it does not exist and lpValue is
/// not NULL.
/// </param>
/// <param name="lpValue">
/// <para>
/// The contents of the environment variable. The maximum size of a user-defined environment variable is 32,767 characters. For more
/// information, see Environment Variables.
/// </para>
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> The total size of the environment block for a process may not exceed 32,767 characters.
/// </para>
/// <para>If this parameter is NULL, the variable is deleted from the current process's environment.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetEnvironmentVariable( _In_ LPCTSTR lpName, _In_opt_ LPCTSTR lpValue); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686206")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetEnvironmentVariable(string lpName, [Optional] string lpValue);
/// <summary>Sets the handle for the specified standard device (standard input, standard output, or standard error).</summary>
/// <param name="nStdHandle">
/// <para>The standard device for which the handle is to be set. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>STD_INPUT_HANDLE (DWORD)-10</term>
/// <term>The standard input device.</term>
/// </item>
/// <item>
/// <term>STD_OUTPUT_HANDLE (DWORD)-11</term>
/// <term>The standard output device.</term>
/// </item>
/// <item>
/// <term>STD_ERROR_HANDLE (DWORD)-12</term>
/// <term>The standard error device.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="hHandle">The handle for the standard device.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetStdHandle( _In_ DWORD nStdHandle, _In_ HANDLE hHandle ); https://docs.microsoft.com/en-us/windows/console/setstdhandle
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetStdHandle(StdHandleType nStdHandle, HFILE hHandle);
/// <summary>Sets the handle for the specified standard device and returns the previous one</summary>
/// <param name="nStdHandle">The standard handle to replace. Can be STD_INPUT_HANDLE, STD_OUTPUT_HANDLE or STD_ERROR_HANDLE</param>
/// <param name="hHandle">The new handle</param>
/// <param name="phPrevValue">
/// A pointer to a handle that receives the previous value. Can be NULL in which case the function behaves exactly as SetStdHandle
/// </param>
/// <returns>Non-zero if the function succeeds, zero otherwise. More information is available via GetLastError</returns>
// BOOL WINAPI SetStdHandleEx (DWORD nStdHandle, HANDLE hHandle, HANDLE* phPrevValue) http://undoc.airesoft.co.uk/kernel32.dll/SetStdHandleEx.php
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetStdHandleEx(StdHandleType nStdHandle, HFILE hHandle, out HFILE phPrevValue);
[DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "GetCommandLine", CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683156")]
private static extern IntPtr GetCommandLineInternal();
[DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "GetEnvironmentStrings", CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683187")]
private static extern IntPtr InternalGetEnvironmentStrings();
}
}