diff --git a/Directory.Build.props b/Directory.Build.props
index 93d1e660..8b7f2bf9 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -15,7 +15,7 @@
en-US
enable
true
- $(NoWarn);NETSDK1138;SYSLIB0003;SYSLIB0004;SYSLIB0011;IL2026;IL2050;IL2075;IL2067;IL2070;IL2072;IL2077;IL2080;IL2087;IL2090;CS0618;CA1401;CA2101;SYSLIB1054;
+ $(NoWarn);NETSDK1138;SYSLIB0003;SYSLIB0004;SYSLIB0011;IL2026;IL2050;IL2075;IL2067;IL2070;IL2072;IL2077;IL2080;IL2087;IL2090;CS0618;CA1041;CA1401;CA2101;SYSLIB1054;SYSLIB1096;
true
diff --git a/PInvoke/SearchApi/SearchApi.cs b/PInvoke/SearchApi/SearchApi.cs
index 10714fd7..72d3d71f 100644
--- a/PInvoke/SearchApi/SearchApi.cs
+++ b/PInvoke/SearchApi/SearchApi.cs
@@ -2863,7 +2863,8 @@ public static partial class SearchApi
// OnItemsChanged( DWORD dwNumberOfChanges, SEARCH_ITEM_CHANGE [] rgDataChangeEntries, DWORD [] rgdwDocIds, HRESULT []
// rghrCompletionCodes );
[PInvokeData("searchapi.h")]
- void OnItemsChanged(uint dwNumberOfChanges, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] SEARCH_ITEM_CHANGE[] rgDataChangeEntries, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] rgdwDocIds, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] HRESULT[] rghrCompletionCodes);
+ void OnItemsChanged(uint dwNumberOfChanges, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] SEARCH_ITEM_CHANGE[] rgDataChangeEntries,
+ [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] rgdwDocIds, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] HRESULT[] rghrCompletionCodes);
}
/// Provides methods for accessing thesaurus information.
@@ -2929,7 +2930,7 @@ public static partial class SearchApi
// https://docs.microsoft.com/en-us/windows/desktop/api/searchapi/nf-searchapi-isearchlanguagesupport-loadwordbreaker HRESULT
// LoadWordBreaker( LCID lcid, REFIID riid, void **ppWordBreaker, LCID *pLcidUsed );
[PInvokeData("searchapi.h")]
- void LoadWordBreaker(uint lcid, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppWordBreaker, out uint pLcidUsed);
+ void LoadWordBreaker(LCID lcid, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppWordBreaker, out LCID pLcidUsed);
/// Retrieves an interface to the word stemmer registered for the specified language code identifier (LCID).
///
@@ -2951,7 +2952,7 @@ public static partial class SearchApi
// https://docs.microsoft.com/en-us/windows/desktop/api/searchapi/nf-searchapi-isearchlanguagesupport-loadstemmer HRESULT
// LoadStemmer( LCID lcid, REFIID riid, void **ppStemmer, LCID *pLcidUsed );
[PInvokeData("searchapi.h")]
- void LoadStemmer(uint lcid, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppStemmer, out uint pLcidUsed);
+ void LoadStemmer(LCID lcid, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppStemmer, out LCID pLcidUsed);
///
/// Determines whether the query token is a prefix of the document token, disregarding case, width, and (optionally) diacritics.
@@ -4086,7 +4087,7 @@ public static partial class SearchApi
// put_QueryContentLocale( LCID lcid );
[PInvokeData("searchapi.h")]
[DispId(0x60010001)]
- uint QueryContentLocale { [param: In] set; get; }
+ LCID QueryContentLocale { [param: In] set; get; }
///
/// Gets or sets the language code identifier (LCID) for the locale to use when parsing Advanced Query Syntax (AQS) keywords.
@@ -4100,7 +4101,7 @@ public static partial class SearchApi
// put_QueryKeywordLocale( LCID lcid );
[PInvokeData("searchapi.h")]
[DispId(0x60010003)]
- uint QueryKeywordLocale { [param: In] set; get; }
+ LCID QueryKeywordLocale { [param: In] set; get; }
/// Gets or sets a value that specifies how query terms are to be expanded.
///
@@ -6065,6 +6066,26 @@ public static partial class SearchApi
HRESULT LoadIFilterWithPrivateComActivation(in FILTERED_DATA_SOURCES filteredSources, [In, MarshalAs(UnmanagedType.Bool)] bool useDefault, out Guid filterClsid, [MarshalAs(UnmanagedType.Bool)] out bool isFilterPrivateComActivated, out IFilter filterObj);
}
+ /// Gets the change notification sink interface.
+ /// The instance.
+ /// Type: ISearchNotifyInlineSite*
+ /// A pointer to your ISearchNotifyInlineSite interface.
+ /// Type: GUID*
+ /// Receives a pointer to the GUID representing the catalog reset. If this GUID changes, all notifications must be resent.
+ /// Type: GUID*
+ /// Receives a pointer to the GUID representing a checkpoint.
+ /// Type: DWORD*
+ /// Receives a pointer to the number indicating the last checkpoint to be saved.
+ /// Receives a pointer to the interface.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/searchapi/nf-searchapi-isearchcatalogmanager-getitemschangedsink HRESULT
+ // GetItemsChangedSink( ISearchNotifyInlineSite *pISearchNotifyInlineSite, REFIID riid, void **ppv, GUID
+ // *pGUIDCatalogResetSignature, GUID *pGUIDCheckPointSignature, DWORD *pdwLastCheckPointNumber );
+ public static ISearchItemsChangedSink GetItemsChangedSink(this ISearchCatalogManager mgr, ISearchNotifyInlineSite pISearchNotifyInlineSite, out Guid pGUIDCatalogResetSignature, out Guid pGUIDCheckPointSignature, out uint pdwLastCheckPointNumber)
+ {
+ mgr.GetItemsChangedSink(pISearchNotifyInlineSite, typeof(ISearchItemsChangedSink).GUID, out var ppv, out pGUIDCatalogResetSignature, out pGUIDCheckPointSignature, out pdwLastCheckPointNumber);
+ return (ISearchItemsChangedSink)ppv;
+ }
+
/// Describes security authentication information for content access.
// https://docs.microsoft.com/en-us/windows/desktop/api/searchapi/ns-searchapi-authentication_info typedef struct
// _AUTHENTICATION_INFO { DWORD dwSize; AUTH_TYPE atAuthenticationType; LPCWSTR pcwszUser; LPCWSTR pcwszPassword; } AUTHENTICATION_INFO;
@@ -6307,7 +6328,7 @@ public static partial class SearchApi
/// Type: LCID
/// The LCID of the column.
///
- public uint lcid;
+ public LCID lcid;
}
/// Specifies the changes to an indexed item.
@@ -6344,7 +6365,8 @@ public static partial class SearchApi
/// or SEARCH_CHANGE_MODIFY notification. In the case of a move, this member contains the new URL of the item.
///
///
- [MarshalAs(UnmanagedType.LPWStr)] public string lpwszURL;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? lpwszURL;
///
/// Type: LPWSTR
@@ -6353,7 +6375,8 @@ public static partial class SearchApi
/// SEARCH_CHANGE_DELETE notification.
///
///
- [MarshalAs(UnmanagedType.LPWStr)] public string lpwszOldURL;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? lpwszOldURL;
}
/// Describes the status of a document to be indexed.
@@ -6542,7 +6565,7 @@ public static partial class SearchApi
/// word breaking of text. If the chunk is neither text-type nor a value-type with data type VT_LPWSTR, VT_LPSTR or VT_BSTR, this
/// field is ignored.
///
- public uint locale;
+ public LCID locale;
///
/// The property to be applied to the chunk. See FULLPROPSPEC. If a filter requires that the same text have more than one
diff --git a/UnitTests/PInvoke/SearchApi/SearchApi.csproj b/UnitTests/PInvoke/SearchApi/SearchApi.csproj
new file mode 100644
index 00000000..d8a8ca21
--- /dev/null
+++ b/UnitTests/PInvoke/SearchApi/SearchApi.csproj
@@ -0,0 +1,8 @@
+
+
+ UnitTest.PInvoke.SearchApi
+
+
+
+
+
\ No newline at end of file
diff --git a/UnitTests/PInvoke/SearchApi/SearchApiTests.cs b/UnitTests/PInvoke/SearchApi/SearchApiTests.cs
new file mode 100644
index 00000000..758f1563
--- /dev/null
+++ b/UnitTests/PInvoke/SearchApi/SearchApiTests.cs
@@ -0,0 +1,64 @@
+using NUnit.Framework;
+using NUnit.Framework.Internal;
+using System.IO;
+using static Vanara.PInvoke.SearchApi;
+
+namespace Vanara.PInvoke.Tests;
+
+[TestFixture]
+public class SearchApiTests
+{
+ ISearchCatalogManager? catalogManager;
+
+ [OneTimeSetUp]
+ public void _Setup()
+ {
+ ISearchManager searchManager = new();
+ catalogManager = searchManager.GetCatalog("SystemIndex");
+ }
+
+ [OneTimeTearDown]
+ public void _TearDown()
+ {
+ }
+
+ //[Test]
+ public void GetItemsChangedSinkTest()
+ {
+ TestInlineSite testInlineSite = new(TestContext.Out);
+ ISearchItemsChangedSink itemsChangedSink = catalogManager!.GetItemsChangedSink(testInlineSite, out _, out _, out _);
+
+ using TemporaryDirectory tempDir = new();
+ string f1 = tempDir.RandomTxtFileFullPath;
+ File.Copy(TestCaseSources.SmallFile, f1);
+ Assert.That(File.Exists(f1), Is.True);
+ string f2 = tempDir.RandomTxtFileFullPath;
+
+ SEARCH_ITEM_CHANGE itemChange = new()
+ {
+ Change = SEARCH_KIND_OF_CHANGE.SEARCH_CHANGE_MOVE_RENAME,
+ Priority = SEARCH_NOTIFICATION_PRIORITY.SEARCH_NORMAL_PRIORITY,
+ pUserData = default, //This is supposed to be a "Pointer to user information", but I have no idea what this means or what it wants
+ lpwszURL = new Uri(f2).AbsoluteUri,
+ lpwszOldURL = new Uri(f1).AbsoluteUri
+ };
+ File.Move(f1, f2);
+ Assert.That(File.Exists(f2), Is.True);
+
+ // I can't get this to work. I get an exception (DTS_E_OLEDBERROR) when trying to call OnItemsChanged.
+ SEARCH_ITEM_CHANGE[] itemsChangedArray = [itemChange];
+ uint[] retInts = [0];
+ HRESULT[] hresults = [0];
+ itemsChangedSink.OnItemsChanged(1, itemsChangedArray, retInts, hresults);
+ Assert.That((int)hresults[0], Is.EqualTo(HRESULT.S_OK));
+ }
+
+ [ComVisible(true), Guid("4da1a242-8634-433a-906d-9bdba3e60b11")]
+ internal class TestInlineSite(TextWriter tw) : ISearchNotifyInlineSite
+ {
+ public void OnItemIndexedStatusChange([In] SEARCH_INDEXING_PHASE sipStatus, [In] uint dwNumEntries,
+ SEARCH_ITEM_INDEXING_STATUS[] rgItemStatusEntries) => tw.WriteLine("OnItemIndexedStatusChange");
+ public void OnCatalogStatusChange(in Guid guidCatalogResetSignature, in Guid guidCheckPointSignature, uint dwLastCheckPointNumber) =>
+ tw.WriteLine("OnCatalogStatusChange");
+ }
+}
\ No newline at end of file
diff --git a/Vanara.sln b/Vanara.sln
index c9a91d75..d84e5f40 100644
--- a/Vanara.sln
+++ b/Vanara.sln
@@ -448,6 +448,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WUApi", "UnitTests\PInvoke\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vanara.WindowsUpdate", "WindowsUpdate\Vanara.WindowsUpdate.csproj", "{DCD4CDCF-F963-48B6-9B8F-1F273C38952F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchApi", "UnitTests\PInvoke\SearchApi\SearchApi.csproj", "{B359422A-F804-46B1-BC79-A55F241C5DF3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -2433,7 +2435,6 @@ Global
{A96CFF10-0967-429A-8700-4A86C97C5603}.Debug|x86.ActiveCfg = Debug|x86
{A96CFF10-0967-429A-8700-4A86C97C5603}.Debug|x86.Build.0 = Debug|x86
{A96CFF10-0967-429A-8700-4A86C97C5603}.DebugNoTests|Any CPU.ActiveCfg = DebugNoTests|Any CPU
- {A96CFF10-0967-429A-8700-4A86C97C5603}.DebugNoTests|Any CPU.Build.0 = DebugNoTests|Any CPU
{A96CFF10-0967-429A-8700-4A86C97C5603}.DebugNoTests|x64.ActiveCfg = DebugNoTests|x64
{A96CFF10-0967-429A-8700-4A86C97C5603}.DebugNoTests|x64.Build.0 = DebugNoTests|x64
{A96CFF10-0967-429A-8700-4A86C97C5603}.DebugNoTests|x86.ActiveCfg = DebugNoTests|x86
@@ -3318,7 +3319,6 @@ Global
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.Debug|x86.ActiveCfg = Debug|x86
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.Debug|x86.Build.0 = Debug|x86
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.DebugNoTests|Any CPU.ActiveCfg = DebugNoTests|Any CPU
- {40E5CA4E-527F-4F79-875D-2342D1136FDD}.DebugNoTests|Any CPU.Build.0 = DebugNoTests|Any CPU
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.DebugNoTests|x64.ActiveCfg = DebugNoTests|x64
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.DebugNoTests|x64.Build.0 = DebugNoTests|x64
{40E5CA4E-527F-4F79-875D-2342D1136FDD}.DebugNoTests|x86.ActiveCfg = DebugNoTests|x86
@@ -3929,6 +3929,22 @@ Global
{DCD4CDCF-F963-48B6-9B8F-1F273C38952F}.Release|x64.Build.0 = Release|x64
{DCD4CDCF-F963-48B6-9B8F-1F273C38952F}.Release|x86.ActiveCfg = Release|x86
{DCD4CDCF-F963-48B6-9B8F-1F273C38952F}.Release|x86.Build.0 = Release|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|x64.ActiveCfg = Debug|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|x64.Build.0 = Debug|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|x86.ActiveCfg = Debug|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Debug|x86.Build.0 = Debug|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.DebugNoTests|Any CPU.ActiveCfg = DebugNoTests|Any CPU
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.DebugNoTests|x64.ActiveCfg = DebugNoTests|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.DebugNoTests|x64.Build.0 = DebugNoTests|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.DebugNoTests|x86.ActiveCfg = DebugNoTests|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.DebugNoTests|x86.Build.0 = DebugNoTests|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Release|x64.ActiveCfg = Release|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Release|x64.Build.0 = Release|x64
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Release|x86.ActiveCfg = Release|x86
+ {B359422A-F804-46B1-BC79-A55F241C5DF3}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4129,6 +4145,7 @@ Global
{9E2D6D4B-69D0-46A0-A18A-186E3FA269BD} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{7A2BF2BB-B565-4F0F-8EBD-5C0A57A0773B} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{4E84A8EA-A180-4897-9542-C529A91702AC} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
+ {B359422A-F804-46B1-BC79-A55F241C5DF3} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}