Fixed and enhanced processenv.h functions

pull/60/head
David Hall 2019-06-25 20:07:28 -06:00
parent 6649425ebb
commit da3fac4ae4
2 changed files with 112 additions and 8 deletions

View File

@ -81,9 +81,8 @@ namespace Vanara.PInvoke
/// <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
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683156")]
public static extern string GetCommandLine();
public static string GetCommandLine() => Marshal.PtrToStringAuto(GetCommandLineInternal());
/// <summary>Retrieves the current directory for the current process.</summary>
/// <param name="nBufferLength">
@ -270,17 +269,17 @@ namespace Vanara.PInvoke
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>
/// <param name="NewEnvironment">The new environment strings as a list of strings.</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>
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("ProcessEnv.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetEnvironmentStringsW(string NewEnvironment);
public static bool SetEnvironmentStrings(IEnumerable<string> NewEnvironment)
{
using (var mem = SafeHGlobalHandle.CreateFromStringList(NewEnvironment, StringListPackMethod.Concatenated, CharSet.Unicode))
return SetEnvironmentStringsW(mem.DangerousGetHandle());
}
/// <summary>Sets the contents of the specified environment variable for the current process.</summary>
/// <param name="lpName">
@ -355,6 +354,22 @@ namespace Vanara.PInvoke
[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)]
private static extern IntPtr GetCommandLineInternal();
/// <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, ExactSpelling = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetEnvironmentStringsW(IntPtr NewEnvironment);
/// <summary>Represents a block of environment strings obtained by <see cref="GetEnvironmentStrings"/> and freed by <see cref="FreeEnvironmentStrings"/>.</summary>
/// <seealso cref="Vanara.InteropServices.GenericSafeHandle"/>
/// <seealso cref="System.Collections.Generic.IEnumerable{T}"/>

View File

@ -0,0 +1,89 @@
using NUnit.Framework;
using System.Runtime.InteropServices;
using System.Text;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke.Tests
{
[TestFixture]
public class ProcessEnvTests
{
[Test]
public void ExpandEnvironmentStringsTest()
{
var sb = new StringBuilder(MAX_PATH);
Assert.That(ExpandEnvironmentStrings("%USERDOMAIN%", sb, MAX_PATH), Is.Not.Zero);
Assert.That(sb.ToString(), Is.EqualTo("AMERICAS"));
}
[Test]
public void GetCommandLineTest()
{
Assert.That(GetCommandLine(), Is.Not.Null);
TestContext.WriteLine(GetCommandLine());
}
[Test]
public void GetEnvironmentStringsTest()
{
var es = GetEnvironmentStrings();
Assert.That(es.IsInvalid, Is.False);
Assert.That(es.Value, Is.Not.Empty);
TestContext.WriteLine(string.Join("\r\n", es));
}
[Test]
public void GetSetCurrentDirectoryTest()
{
var sb = new StringBuilder(MAX_PATH);
Assert.That(GetCurrentDirectory((uint)sb.Capacity, sb), Is.GreaterThan(0));
Assert.That(sb.ToString().StartsWith("C:"));
TestContext.WriteLine(sb);
Assert.That(SetCurrentDirectory(@"C:\Temp"), Is.True);
var sb2 = new StringBuilder(MAX_PATH);
Assert.That(GetCurrentDirectory((uint)sb2.Capacity, sb2), Is.GreaterThan(0));
Assert.That(sb2.ToString(), Is.EqualTo(@"C:\Temp"));
Assert.That(SetCurrentDirectory(sb.ToString()));
}
[Test]
public void GetSetEnvironmentVariableTest()
{
var str = System.IO.Path.GetRandomFileName();
Assert.That(SetEnvironmentVariable(str, "Value"), Is.True);
var sb = new StringBuilder(MAX_PATH);
Assert.That(GetEnvironmentVariable(str, sb, (uint)sb.Capacity), Is.Not.Zero);
Assert.That(sb.ToString(), Is.EqualTo("Value"));
Assert.That(SetEnvironmentVariable(str), Is.True);
}
[Test]
public void GetStdHandleTest()
{
Assert.That(GetStdHandle(StdHandleType.STD_ERROR_HANDLE).IsInvalid, Is.False);
Assert.That(GetStdHandle(StdHandleType.STD_INPUT_HANDLE).IsInvalid, Is.False);
Assert.That(GetStdHandle(StdHandleType.STD_OUTPUT_HANDLE).IsInvalid, Is.False);
}
[Test]
public void NeedCurrentDirectoryForExePathTest()
{
Assert.That(NeedCurrentDirectoryForExePath("cmd.exe"), Is.True);
Assert.That(NeedCurrentDirectoryForExePath(@"testApp.exe"), Is.True);
}
[Test]
public void SearchPathTest()
{
var sb = new StringBuilder(MAX_PATH);
Assert.That(SearchPath(null, "notepad.exe", null, (uint)sb.Capacity, sb, out var ptr), Is.Not.Zero);
Assert.That(sb.ToString().StartsWith("C:"));
Assert.That(Marshal.PtrToStringAuto(ptr), Is.EqualTo("notepad.exe"));
}
}
}