diff --git a/PInvoke/Kernel32/WinBase.Profile.cs b/PInvoke/Kernel32/WinBase.Profile.cs
index e690455a..9368c114 100644
--- a/PInvoke/Kernel32/WinBase.Profile.cs
+++ b/PInvoke/Kernel32/WinBase.Profile.cs
@@ -1,6 +1,7 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
+using Vanara.InteropServices;
namespace Vanara.PInvoke
{
@@ -9,16 +10,17 @@ namespace Vanara.PInvoke
/// Retrieves an integer associated with a key in the specified section of an initialization file.
/// The name of the section in the initialization file.
///
- /// The name of the key whose value is to be retrieved. This value is in the form of a string; the GetPrivateProfileInt function converts the
- /// string into an integer and returns the integer.
+ /// The name of the key whose value is to be retrieved. This value is in the form of a string; the GetPrivateProfileInt
+ /// function converts the string into an integer and returns the integer.
///
/// The default value to return if the key name cannot be found in the initialization file.
///
- /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
+ /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file
+ /// in the Windows directory.
///
///
- /// The return value is the integer equivalent of the string following the specified key name in the specified initialization file. If the key is not
- /// found, the return value is the specified default value.
+ /// The return value is the integer equivalent of the string following the specified key name in the specified initialization file.
+ /// If the key is not found, the return value is the specified default value.
///
// UINT WINAPI GetPrivateProfileInt( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ INT nDefault, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724345(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
@@ -28,38 +30,41 @@ namespace Vanara.PInvoke
/// Retrieves all the keys and values for the specified section of an initialization file.
/// The name of the section in the initialization file.
///
- /// A pointer to a buffer that receives the key name and value pairs associated with the named section. The buffer is filled with one or more
- /// null-terminated strings; the last string is followed by a second null character.
+ /// A pointer to a buffer that receives the key name and value pairs associated with the named section. The buffer is filled with one
+ /// or more null-terminated strings; the last string is followed by a second null character.
///
///
/// The size of the buffer pointed to by the lpReturnedString parameter, in characters. The maximum profile section size is 32,767 characters.
///
///
- /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
+ /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file
+ /// in the Windows directory.
///
///
- /// The return value specifies the number of characters copied to the buffer, not including the terminating null character. If the buffer is not large
- /// enough to contain all the key name and value pairs associated with the named section, the return value is equal to nSize minus two.
+ /// The return value specifies the number of characters copied to the buffer, not including the terminating null character. If the
+ /// buffer is not large enough to contain all the key name and value pairs associated with the named section, the return value is
+ /// equal to nSize minus two.
///
- // DWORD WINAPI GetPrivateProfileSection( _In_ LPCTSTR lpAppName, _Out_ LPTSTR lpReturnedString, _In_ DWORD nSize, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724348(v=vs.85).aspx
+ // DWORD WINAPI GetPrivateProfileSection( _In_ LPCTSTR lpAppName, _Out_ LPTSTR lpReturnedString, _In_ DWORD nSize, _In_ LPCTSTR
+ // lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724348(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724348")]
public static extern uint GetPrivateProfileSection(string lpAppName, StringBuilder lpReturnedString, uint nSize, string lpFileName);
/// Retrieves the names of all sections in an initialization file.
///
- /// A pointer to a buffer that receives the section names associated with the named file. The buffer is filled with one or more null-terminated
- /// strings; the last string is followed by a second null character.
+ /// A pointer to a buffer that receives the section names associated with the named file. The buffer is filled with one or more
+ /// null-terminated strings; the last string is followed by a second null character.
///
/// The size of the buffer pointed to by the lpszReturnBuffer parameter, in characters.
///
- /// The name of the initialization file. If this parameter is NULL, the function searches the Win.ini file. If this parameter does not contain a
- /// full path to the file, the system searches for the file in the Windows directory.
+ /// The name of the initialization file. If this parameter is NULL, the function searches the Win.ini file. If this parameter
+ /// does not contain a full path to the file, the system searches for the file in the Windows directory.
///
///
- /// The return value specifies the number of characters copied to the specified buffer, not including the terminating null character. If the
- /// buffer is not large enough to contain all the section names associated with the specified initialization file, the return value is equal to the size
- /// specified by nSize minus two.
+ /// The return value specifies the number of characters copied to the specified buffer, not including the terminating null
+ /// character. If the buffer is not large enough to contain all the section names associated with the specified initialization file,
+ /// the return value is equal to the size specified by nSize minus two.
///
// DWORD WINAPI GetPrivateProfileSectionNames( _Out_ LPTSTR lpszReturnBuffer, _In_ DWORD nSize, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724352(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
@@ -68,100 +73,130 @@ namespace Vanara.PInvoke
/// Retrieves a string from the specified section in an initialization file.
///
- /// The name of the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section
- /// names in the file to the supplied buffer.
+ /// The name of the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function
+ /// copies all section names in the file to the supplied buffer.
///
///
- /// The name of the key whose associated string is to be retrieved. If this parameter is NULL, all key names in the section specified by the
- /// lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.
+ /// The name of the key whose associated string is to be retrieved. If this parameter is NULL, all key names in the section
+ /// specified by the lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.
///
///
///
- /// A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the
- /// lpReturnedString buffer. If this parameter is NULL, the default is an empty string, "".
+ /// A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the
+ /// default string to the lpReturnedString buffer. If this parameter is NULL, the default is an empty string, "".
///
///
- /// Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to
- /// strip any trailing blanks.
+ /// Avoid specifying a default string with trailing blank characters. The function inserts a null character in the
+ /// lpReturnedString buffer to strip any trailing blanks.
///
///
/// A pointer to the buffer that receives the retrieved string.
/// The size of the buffer pointed to by the lpReturnedString parameter, in characters.
///
- /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
+ /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file
+ /// in the Windows directory.
///
///
/// The return value is the number of characters copied to the buffer, not including the terminating null character.
///
- /// If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is
- /// truncated and followed by a null character, and the return value is equal to nSize minus one.
+ /// If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string,
+ /// the string is truncated and followed by a null character, and the return value is equal to nSize minus one.
///
///
- /// If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is
- /// truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.
+ /// If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the
+ /// last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.
///
///
- /// In the event the initialization file specified by lpFileName is not found, or contains invalid values, this function will set errorno with a
- /// value of '0x2' (File Not Found). To retrieve extended error information, call GetLastError.
+ /// In the event the initialization file specified by lpFileName is not found, or contains invalid values, this function will set
+ /// errorno with a value of '0x2' (File Not Found). To retrieve extended error information, call GetLastError.
///
///
- // DWORD WINAPI GetPrivateProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpDefault, _Out_ LPTSTR lpReturnedString, _In_
- // DWORD nSize, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724353(v=vs.85).aspx
+ // DWORD WINAPI GetPrivateProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpDefault, _Out_ LPTSTR
+ // lpReturnedString, _In_ DWORD nSize, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724353(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724353")]
public static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);
///
- /// Retrieves the data associated with a key in the specified section of an initialization file. As it retrieves the data, the function calculates a
- /// checksum and compares it with the checksum calculated by the WritePrivateProfileStruct function when the data was added to the file.
+ /// Retrieves the data associated with a key in the specified section of an initialization file. As it retrieves the data, the
+ /// function calculates a checksum and compares it with the checksum calculated by the WritePrivateProfileStruct function when
+ /// the data was added to the file.
///
/// The name of the section in the initialization file.
/// The name of the key whose data is to be retrieved.
/// A pointer to the buffer that receives the data associated with the file, section, and key names.
/// The size of the buffer pointed to by the lpStruct parameter, in bytes.
///
- /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
+ /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file
+ /// in the Windows directory.
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero.
///
- // BOOL WINAPI GetPrivateProfileStruct( _In_ LPCTSTR lpszSection, _In_ LPCTSTR lpszKey, _Out_ LPVOID lpStruct, _In_ UINT uSizeStruct, _In_ LPCTSTR
- // szFile); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724356(v=vs.85).aspx
+ // BOOL WINAPI GetPrivateProfileStruct( _In_ LPCTSTR lpszSection, _In_ LPCTSTR lpszKey, _Out_ LPVOID lpStruct, _In_ UINT uSizeStruct,
+ // _In_ LPCTSTR szFile); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724356(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724356")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetPrivateProfileStruct(string lpszSection, string lpszKey, IntPtr lpStruct, uint uSizeStruct, string szFile);
+ ///
+ /// Retrieves the data associated with a key in the specified section of an initialization file. As it retrieves the data, the
+ /// function calculates a checksum and compares it with the checksum calculated by the WritePrivateProfileStruct function when
+ /// the data was added to the file.
+ ///
+ /// The type of the structure to retrieve.
+ /// The name of the section in the initialization file.
+ /// The name of the key whose data is to be retrieved.
+ /// Receives the data associated with the file, section, and key names.
+ ///
+ /// The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file
+ /// in the Windows directory.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero.
+ ///
+ public static bool GetPrivateProfileStruct(string lpszSection, string lpszKey, out T lpStruct, string szFile) where T : unmanaged
+ {
+ using (var mem = SafeHGlobalHandle.CreateFromStructure())
+ {
+ var b = GetPrivateProfileStruct(lpszSection, lpszKey, mem, mem.Size, szFile);
+ lpStruct = mem.ToStructure();
+ return b;
+ }
+ }
+
/// Retrieves an integer from a key in the specified section of the Win.ini file.
/// The name of the section containing the key name.
///
- /// The name of the key whose value is to be retrieved. This value is in the form of a string; the GetProfileInt function converts the string into
- /// an integer and returns the integer.
+ /// The name of the key whose value is to be retrieved. This value is in the form of a string; the GetProfileInt function
+ /// converts the string into an integer and returns the integer.
///
/// The default value to return if the key name cannot be found in the initialization file.
///
- /// The return value is the integer equivalent of the string following the key name in Win.ini. If the function cannot find the key, the return value is
- /// the default value. If the value of the key is less than zero, the return value is zero.
+ /// The return value is the integer equivalent of the string following the key name in Win.ini. If the function cannot find the key,
+ /// the return value is the default value. If the value of the key is less than zero, the return value is zero.
///
// UINT WINAPI GetProfileInt( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ INT nDefault); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724360(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724360")]
- [return: MarshalAs(UnmanagedType.Bool)]
public static extern uint GetProfileInt(string lpAppName, string lpKeyName, int nDefault);
/// Retrieves all the keys and values for the specified section of the Win.ini file.
/// The name of the section in the Win.ini file.
///
- /// A pointer to a buffer that receives the keys and values associated with the named section. The buffer is filled with one or more null-terminated
- /// strings; the last string is followed by a second null character.
+ /// A pointer to a buffer that receives the keys and values associated with the named section. The buffer is filled with one or more
+ /// null-terminated strings; the last string is followed by a second null character.
///
///
/// The size of the buffer pointed to by the lpReturnedString parameter, in characters. The maximum profile section size is 32,767 characters.
///
///
- /// The return value specifies the number of characters copied to the specified buffer, not including the terminating null character. If the buffer is
- /// not large enough to contain all the keys and values associated with the named section, the return value is equal to the size specified by nSize minus two.
+ /// The return value specifies the number of characters copied to the specified buffer, not including the terminating null character.
+ /// If the buffer is not large enough to contain all the keys and values associated with the named section, the return value is equal
+ /// to the size specified by nSize minus two.
///
// DWORD WINAPI GetProfileSection( _In_ LPCTSTR lpAppName, _Out_ LPTSTR lpReturnedString, _In_ DWORD nSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724363(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
@@ -170,20 +205,22 @@ namespace Vanara.PInvoke
/// Retrieves the string associated with a key in the specified section of the Win.ini file.
///
- /// The name of the section containing the key. If this parameter is NULL, the function copies all section names in the file to the supplied buffer.
+ /// The name of the section containing the key. If this parameter is NULL, the function copies all section names in the file
+ /// to the supplied buffer.
///
///
- /// The name of the key whose associated string is to be retrieved. If this parameter is NULL, the function copies all keys in the given section
- /// to the supplied buffer. Each string is followed by a null character, and the final string is followed by a second null character.
+ /// The name of the key whose associated string is to be retrieved. If this parameter is NULL, the function copies all keys in
+ /// the given section to the supplied buffer. Each string is followed by a null character, and the final string is followed by
+ /// a second null character.
///
///
///
- /// A default string. If the lpKeyName key cannot be found in the initialization file, GetProfileString copies the default string to the
- /// lpReturnedString buffer. If this parameter is NULL, the default is an empty string, "".
+ /// A default string. If the lpKeyName key cannot be found in the initialization file, GetProfileString copies the default
+ /// string to the lpReturnedString buffer. If this parameter is NULL, the default is an empty string, "".
///
///
- /// Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to
- /// strip any trailing blanks.
+ /// Avoid specifying a default string with trailing blank characters. The function inserts a null character in the
+ /// lpReturnedString buffer to strip any trailing blanks.
///
///
/// A pointer to a buffer that receives the character string.
@@ -191,31 +228,36 @@ namespace Vanara.PInvoke
///
/// The return value is the number of characters copied to the buffer, not including the null-terminating character.
///
- /// If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is
- /// truncated and followed by a null character, and the return value is equal to nSize minus one.
+ /// If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string,
+ /// the string is truncated and followed by a null character, and the return value is equal to nSize minus one.
///
///
- /// If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is
- /// truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.
+ /// If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the
+ /// last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.
///
///
- // DWORD WINAPI GetProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpDefault, _Out_ LPTSTR lpReturnedString, _In_ DWORD
- // nSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724366(v=vs.85).aspx
+ // DWORD WINAPI GetProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpDefault, _Out_ LPTSTR
+ // lpReturnedString, _In_ DWORD nSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724366(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724366")]
public static extern uint GetProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize);
/// Replaces the keys and values for the specified section in an initialization file.
- /// The name of the section in which data is written. This section name is typically the name of the calling application.
- /// The new key names and associated values that are to be written to the named section. This string is limited to 65,535 bytes.
+ ///
+ /// The name of the section in which data is written. This section name is typically the name of the calling application.
+ ///
+ ///
+ /// The new key names and associated values that are to be written to the named section. This string is limited to 65,535 bytes.
+ ///
///
///
- /// The name of the initialization file. If this parameter does not contain a full path for the file, the function searches the Windows directory for the
- /// file. If the file does not exist and lpFileName does not contain a full path, the function creates the file in the Windows directory.
+ /// The name of the initialization file. If this parameter does not contain a full path for the file, the function searches the
+ /// Windows directory for the file. If the file does not exist and lpFileName does not contain a full path, the function creates the
+ /// file in the Windows directory.
///
///
- /// If the file exists and was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function creates a
- /// file using ANSI characters.
+ /// If the file exists and was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the
+ /// function creates a file using ANSI characters.
///
///
///
@@ -230,79 +272,117 @@ namespace Vanara.PInvoke
/// Copies a string into the specified section of an initialization file.
///
- /// The name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section is
- /// case-independent; the string can be any combination of uppercase and lowercase letters.
+ /// The name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section
+ /// is case-independent; the string can be any combination of uppercase and lowercase letters.
///
///
- /// The name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this parameter is
- /// NULL, the entire section, including all entries within the section, is deleted.
+ /// The name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this
+ /// parameter is NULL, the entire section, including all entries within the section, is deleted.
///
///
- /// A null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName parameter is deleted.
+ /// A null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName
+ /// parameter is deleted.
///
///
/// The name of the initialization file.
///
- /// If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
+ /// If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function
+ /// writes ANSI characters.
///
///
///
/// If the function successfully copies the string to the initialization file, the return value is nonzero.
///
- /// If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is zero. To get
- /// extended error information, call GetLastError.
+ /// If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is
+ /// zero. To get extended error information, call GetLastError.
///
///
- // BOOL WINAPI WritePrivateProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpString, _In_ LPCTSTR lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms725501(v=vs.85).aspx
+ // BOOL WINAPI WritePrivateProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpString, _In_ LPCTSTR
+ // lpFileName); https://msdn.microsoft.com/en-us/library/windows/desktop/ms725501(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms725501")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
///
- /// Copies data into a key in the specified section of an initialization file. As it copies the data, the function calculates a checksum and appends it
- /// to the end of the data. The GetPrivateProfileStruct function uses the checksum to ensure the integrity of the data.
+ /// Copies data into a key in the specified section of an initialization file. As it copies the data, the function calculates a
+ /// checksum and appends it to the end of the data. The GetPrivateProfileStruct function uses the checksum to ensure the
+ /// integrity of the data.
///
///
- /// The name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section is case
- /// independent, the string can be any combination of uppercase and lowercase letters.
+ /// The name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section
+ /// is case independent, the string can be any combination of uppercase and lowercase letters.
///
///
- /// The name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this parameter is
- /// NULL, the entire section, including all keys and entries within the section, is deleted.
+ /// The name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this
+ /// parameter is NULL, the entire section, including all keys and entries within the section, is deleted.
///
/// The data to be copied. If this parameter is NULL, the key is deleted.
/// The size of the buffer pointed to by the lpStruct parameter, in bytes.
///
/// The name of the initialization file. If this parameter is NULL, the information is copied into the Win.ini file.
///
- /// If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
+ /// If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function
+ /// writes ANSI characters.
///
///
///
/// If the function successfully copies the string to the initialization file, the return value is nonzero.
///
- /// If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is zero. To get
- /// extended error information, call GetLastError.
+ /// If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is
+ /// zero. To get extended error information, call GetLastError.
///
///
- // BOOL WINAPI WritePrivateProfileStruct( _In_ LPCTSTR lpszSection, _In_ LPCTSTR lpszKey, _In_ LPVOID lpStruct, _In_ UINT uSizeStruct, _In_ LPCTSTR
- // szFile); https://msdn.microsoft.com/en-us/library/windows/desktop/ms725502(v=vs.85).aspx
+ // BOOL WINAPI WritePrivateProfileStruct( _In_ LPCTSTR lpszSection, _In_ LPCTSTR lpszKey, _In_ LPVOID lpStruct, _In_ UINT
+ // uSizeStruct, _In_ LPCTSTR szFile); https://msdn.microsoft.com/en-us/library/windows/desktop/ms725502(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms725502")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WritePrivateProfileStruct(string lpszSection, string lpszKey, [In] IntPtr lpStruct, uint uSizeStruct, string szFile);
///
- /// Replaces the contents of the specified section in the Win.ini file with specified keys and values. If Win.ini uses Unicode characters, the function
- /// writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
+ /// Copies data into a key in the specified section of an initialization file. As it copies the data, the function calculates a
+ /// checksum and appends it to the end of the data. The GetPrivateProfileStruct function uses the checksum to ensure the
+ /// integrity of the data.
+ ///
+ ///
+ /// The name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section
+ /// is case independent, the string can be any combination of uppercase and lowercase letters.
+ ///
+ ///
+ /// The name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this
+ /// parameter is NULL, the entire section, including all keys and entries within the section, is deleted.
+ ///
+ /// The data to be copied.
+ ///
+ /// The name of the initialization file. If this parameter is NULL, the information is copied into the Win.ini file.
+ ///
+ /// If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function
+ /// writes ANSI characters.
+ ///
+ ///
+ ///
+ /// If the function successfully copies the string to the initialization file, the return value is nonzero.
+ ///
+ /// If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is
+ /// zero. To get extended error information, call GetLastError.
+ ///
+ ///
+ public static bool WritePrivateProfileStruct(string lpszSection, string lpszKey, in T lpStruct, string szFile) where T : unmanaged =>
+ WritePrivateProfileStruct(lpszSection, lpszKey, new PinnedObject(lpStruct), (uint)Marshal.SizeOf(lpStruct), szFile);
+
+ ///
+ /// Replaces the contents of the specified section in the Win.ini file with specified keys and values. If Win.ini uses Unicode
+ /// characters, the function writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
///
/// The name of the section. This section name is typically the name of the calling application.
///
- /// The new key names and associated values that are to be written to the named section. This string is limited to 65,535 bytes.
///
- /// If the file exists and was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function creates a
- /// file using ANSI characters.
+ /// The new key names and associated values that are to be written to the named section. This string is limited to 65,535 bytes.
+ ///
+ ///
+ /// If the file exists and was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the
+ /// function creates a file using ANSI characters.
///
///
///
@@ -316,23 +396,27 @@ namespace Vanara.PInvoke
public static extern bool WriteProfileSection(string lpAppName, string lpString);
///
- /// Copies a string into the specified section of the Win.ini file. If Win.ini uses Unicode characters, the function writes Unicode characters to the
- /// file. Otherwise, the function writes ANSI characters.
+ /// Copies a string into the specified section of the Win.ini file. If Win.ini uses Unicode characters, the function writes Unicode
+ /// characters to the file. Otherwise, the function writes ANSI characters.
///
///
- /// The section to which the string is to be copied. If the section does not exist, it is created. The name of the section is not case-sensitive; the
- /// string can be any combination of uppercase and lowercase letters.
+ /// The section to which the string is to be copied. If the section does not exist, it is created. The name of the section is not
+ /// case-sensitive; the string can be any combination of uppercase and lowercase letters.
///
///
- /// The key to be associated with the string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the
- /// entire section, including all entries in the section, is deleted.
+ /// The key to be associated with the string. If the key does not exist in the specified section, it is created. If this parameter is
+ /// NULL, the entire section, including all entries in the section, is deleted.
///
///
- /// A null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName parameter is deleted.
+ /// A null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName
+ /// parameter is deleted.
///
///
/// If the function successfully copies the string to the Win.ini file, the return value is nonzero.
- /// If the function fails, or if it flushes the cached version of Win.ini, the return value is zero. To get extended error information, call GetLastError.
+ ///
+ /// If the function fails, or if it flushes the cached version of Win.ini, the return value is zero. To get extended error
+ /// information, call GetLastError.
+ ///
///
// BOOL WINAPI WriteProfileString( _In_ LPCTSTR lpAppName, _In_ LPCTSTR lpKeyName, _In_ LPCTSTR lpString); https://msdn.microsoft.com/en-us/library/windows/desktop/ms725504(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
diff --git a/UnitTests/PInvoke/Kernel32/Kernel32.csproj b/UnitTests/PInvoke/Kernel32/Kernel32.csproj
index d190ff90..eed23566 100644
--- a/UnitTests/PInvoke/Kernel32/Kernel32.csproj
+++ b/UnitTests/PInvoke/Kernel32/Kernel32.csproj
@@ -48,6 +48,7 @@
+
diff --git a/UnitTests/PInvoke/Kernel32/WinBase.ProfileTests.cs b/UnitTests/PInvoke/Kernel32/WinBase.ProfileTests.cs
new file mode 100644
index 00000000..8782d7ad
--- /dev/null
+++ b/UnitTests/PInvoke/Kernel32/WinBase.ProfileTests.cs
@@ -0,0 +1,76 @@
+using NUnit.Framework;
+using System.Text;
+using static Vanara.PInvoke.Kernel32;
+
+namespace Vanara.PInvoke.Tests
+{
+ [TestFixture]
+ public partial class WinBaseTests_Profile
+ {
+ [Test]
+ public void PrivateProfileTest()
+ {
+ const string sec = "Section";
+
+ using (var tmp = new TempFile(""))
+ {
+ Assert.That(WritePrivateProfileSection(sec, "Key0=10\0", tmp.FullName), ResultIs.Successful);
+ Assert.That(WritePrivateProfileString(sec, "Key1", "Value1", tmp.FullName), ResultIs.Successful);
+ Assert.That(WritePrivateProfileStruct(sec, "Key2", new RECT(1, 2, 3, 4), tmp.FullName), ResultIs.Successful);
+ Assert.That(WritePrivateProfileStruct(sec, "Key3", 4, tmp.FullName), ResultIs.Successful);
+ TestContext.WriteLine(System.IO.File.ReadAllText(tmp.FullName));
+
+ Assert.That(GetPrivateProfileInt(sec, "Key0", 0, tmp.FullName), Is.EqualTo(10));
+ Assert.That(GetPrivateProfileInt(sec, "Key3", 0, tmp.FullName), Is.Not.EqualTo(4));
+ Assert.That(GetPrivateProfileInt(sec, "Key4", 0, tmp.FullName), Is.EqualTo(0));
+
+ var sb = new StringBuilder(1024);
+ Assert.That(GetPrivateProfileSection(sec, sb, (uint)sb.Capacity, tmp.FullName), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ TestContext.WriteLine(sb);
+
+ sb.Clear();
+ Assert.That(GetPrivateProfileSectionNames(sb, (uint)sb.Capacity, tmp.FullName), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ TestContext.WriteLine(sb);
+
+ sb.Clear();
+ Assert.That(GetPrivateProfileString(sec, "Key0", null, sb, (uint)sb.Capacity, tmp.FullName), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ Assert.That(sb.ToString(), Is.EqualTo("10"));
+ sb.Clear();
+ Assert.That(GetPrivateProfileString(sec, "Key1", null, sb, (uint)sb.Capacity, tmp.FullName), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ Assert.That(sb.ToString(), Is.EqualTo("Value1"));
+ sb.Clear();
+ Assert.That(GetPrivateProfileString(sec, "Key3", null, sb, (uint)sb.Capacity, tmp.FullName), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ Assert.That(sb.ToString(), Is.EqualTo("0400000004"));
+
+ Assert.That(GetPrivateProfileStruct(sec, "Key2", out RECT r, tmp.FullName), Is.True);
+ Assert.That(r.bottom, Is.EqualTo(4));
+ Assert.That(GetPrivateProfileStruct(sec, "Key3", out int i, tmp.FullName), Is.True);
+ Assert.That(i, Is.EqualTo(4));
+ Assert.That(GetPrivateProfileStruct(sec, "Key0", out i, tmp.FullName), Is.False);
+ }
+ }
+
+ [Test]
+ public void ProfileTest()
+ {
+ const string sec = "Section";
+
+ Assert.That(WriteProfileSection(sec, "Key0=10\0"), ResultIs.Successful);
+ Assert.That(WriteProfileString(sec, "Key1", "Value1"), ResultIs.Successful);
+
+ Assert.That(GetProfileInt(sec, "Key0", 0), Is.EqualTo(10));
+ Assert.That(GetProfileInt(sec, "Key4", 0), Is.EqualTo(0));
+
+ var sb = new StringBuilder(1024);
+ Assert.That(GetProfileSection(sec, sb, (uint)sb.Capacity), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ TestContext.WriteLine(sb);
+
+ sb.Clear();
+ Assert.That(GetProfileString(sec, "Key0", null, sb, (uint)sb.Capacity), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ Assert.That(sb.ToString(), Is.EqualTo("10"));
+ sb.Clear();
+ Assert.That(GetProfileString(sec, "Key1", null, sb, (uint)sb.Capacity), Is.GreaterThan(0).And.Not.EqualTo(sb.Capacity - 2));
+ Assert.That(sb.ToString(), Is.EqualTo("Value1"));
+ }
+ }
+}
\ No newline at end of file