/// <summary> /// Create a simple search folder. Once the appropriate parameters are set, /// the search folder can be enumerated to get the search results. /// </summary> /// <param name="searchCondition">Specific condition on which to perform the search (property and expected value)</param> /// <param name="searchScopePath">List of folders/paths to perform the search on. These locations need to be indexed by the system.</param> public ShellSearchFolder(SearchCondition searchCondition, params ShellItem[] searchScopePath) { NativeSearchFolderItemFactory = (ISearchFolderItemFactory)new SearchFolderItemFactoryCoClass(); this.SearchCondition = searchCondition; if (searchScopePath != null && searchScopePath.Length > 0 && searchScopePath[0] != null) { this.SearchScopePaths = searchScopePath.Select(cont => cont.ParsingName); } ComInterface = this.m_SearchComInterface; }
/* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and constant value. /// </summary> /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> /// <param name="value">The constant value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(string propertyName, string value, SearchConditionOperation operation) { using (PropVariant propVar = new PropVariant(value)) { return CreateLeafCondition(propertyName, propVar, null, operation); } } /// <summary> /// Creates a leaf condition node that represents a comparison of property value and constant value. /// Overload method takes a DateTime parameter for the comparison value. /// </summary> /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> /// <param name="value">The DateTime value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(string propertyName, DateTime value, SearchConditionOperation operation) { using (PropVariant propVar = new PropVariant(value)) { return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.DateTime", operation); } } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Integer value. /// </summary> /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> /// <param name="value">The Integer value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(string propertyName, int value, SearchConditionOperation operation) { using (PropVariant propVar = new PropVariant(value)) { return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Integer", operation); } } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Boolean value. /// </summary> /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> /// <param name="value">The Boolean value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(string propertyName, bool value, SearchConditionOperation operation) { using (PropVariant propVar = new PropVariant(value)) { return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Boolean", operation); } } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Floating Point value. /// </summary> /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> /// <param name="value">The Floating Point value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(string propertyName, double value, SearchConditionOperation operation) { using (PropVariant propVar = new PropVariant(value)) { return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.FloatingPoint", operation); } } */ /* [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] private static SearchCondition CreateLeafCondition(string propertyName, PropVariant propVar, string valueType, SearchConditionOperation operation) { IConditionFactory nativeConditionFactory = null; SearchCondition condition = null; try { // Same as the native "IConditionFactory:MakeLeaf" method nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); ICondition nativeCondition = null; if (string.IsNullOrEmpty(propertyName) || propertyName.ToUpperInvariant() == "SYSTEM.NULL") { propertyName = null; } HResult hr = HResult.S_FALSE; hr = nativeConditionFactory.MakeLeaf(propertyName, operation, valueType, propVar, null, null, null, false, out nativeCondition); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } // Create our search condition and set the various properties. condition = new SearchCondition(nativeCondition); } finally { if (nativeConditionFactory != null) { Marshal.ReleaseComObject(nativeConditionFactory); } } return condition; } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and constant value. /// </summary> /// <param name="propertyKey">The property to be compared.</param> /// <param name="value">The constant value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, string value, SearchConditionOperation operation) { string canonicalName; PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); if (string.IsNullOrEmpty(canonicalName)) { throw new ArgumentException("Invalid PK", "propertyKey"); } return CreateLeafCondition(canonicalName, value, operation); } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and constant value. /// Overload method takes a DateTime parameter for the comparison value. /// </summary> /// <param name="propertyKey">The property to be compared.</param> /// <param name="value">The DateTime value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, DateTime value, SearchConditionOperation operation) { string canonicalName; PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); if (string.IsNullOrEmpty(canonicalName)) { throw new ArgumentException("Invalid PK", "propertyKey"); } return CreateLeafCondition(canonicalName, value, operation); } */ /* /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Boolean value. /// Overload method takes a DateTime parameter for the comparison value. /// </summary> /// <param name="propertyKey">The property to be compared.</param> /// <param name="value">The boolean value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, bool value, SearchConditionOperation operation) { string canonicalName; PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); if (string.IsNullOrEmpty(canonicalName)) { throw new ArgumentException("Invalid PK", "propertyKey"); } return CreateLeafCondition(canonicalName, value, operation); } /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Floating Point value. /// Overload method takes a DateTime parameter for the comparison value. /// </summary> /// <param name="propertyKey">The property to be compared.</param> /// <param name="value">The Floating Point value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, double value, SearchConditionOperation operation) { string canonicalName; PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); if (string.IsNullOrEmpty(canonicalName)) { throw new ArgumentException("Invalid PK", "propertyKey"); } return CreateLeafCondition(canonicalName, value, operation); } /// <summary> /// Creates a leaf condition node that represents a comparison of property value and Integer value. /// Overload method takes a DateTime parameter for the comparison value. /// </summary> /// <param name="propertyKey">The property to be compared.</param> /// <param name="value">The Integer value against which the property value should be compared.</param> /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> /// <returns>SearchCondition based on the given parameters</returns> /// <remarks> /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find /// the properties that are indexed, look for the specific property's property description and /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. /// </remarks> public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, int value, SearchConditionOperation operation) { string canonicalName; PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); if (string.IsNullOrEmpty(canonicalName)) { throw new ArgumentException("Invalid PK", "propertyKey"); } return CreateLeafCondition(canonicalName, value, operation); } /// <summary> /// Creates a condition node that is a logical conjunction ("AND") or disjunction ("OR") /// of a collection of subconditions. /// </summary> /// <param name="conditionType">The SearchConditionType of the condition node. /// Must be either AndCondition or OrCondition.</param> /// <param name="simplify">TRUE to logically simplify the result, if possible; /// then the result will not necessarily to be of the specified kind. FALSE if the result should /// have exactly the prescribed structure. An application that plans to execute a query based on the /// condition tree would typically benefit from setting this parameter to TRUE. </param> /// <param name="conditionNodes">Array of subconditions</param> /// <returns>New SearchCondition based on the operation</returns> public static SearchCondition CreateAndOrCondition(SearchConditionType conditionType, bool simplify, params SearchCondition[] conditionNodes) { // Same as the native "IConditionFactory:MakeAndOr" method IConditionFactory nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); ICondition result = null; try { // List<ICondition> conditionList = new List<ICondition>(); if (conditionNodes != null) { foreach (SearchCondition c in conditionNodes) { conditionList.Add(c.NativeSearchCondition); } } IEnumUnknown subConditions = new EnumUnknownClass(conditionList.ToArray()); HResult hr = nativeConditionFactory.MakeAndOr(conditionType, subConditions, simplify, out result); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } } finally { if (nativeConditionFactory != null) { Marshal.ReleaseComObject(nativeConditionFactory); } } return new SearchCondition(result); } /// <summary> /// Creates a condition node that is a logical negation (NOT) of another condition /// (a subnode of this node). /// </summary> /// <param name="conditionToBeNegated">SearchCondition node to be negated.</param> /// <param name="simplify">True to logically simplify the result if possible; False otherwise. /// In a query builder scenario, simplyfy should typically be set to false.</param> /// <returns>New SearchCondition</returns> public static SearchCondition CreateNotCondition(SearchCondition conditionToBeNegated, bool simplify) { if (conditionToBeNegated == null) { throw new ArgumentNullException("conditionToBeNegated"); } // Same as the native "IConditionFactory:MakeNot" method IConditionFactory nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); ICondition result; try { HResult hr = nativeConditionFactory.MakeNot(conditionToBeNegated.NativeSearchCondition, simplify, out result); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } } finally { if (nativeConditionFactory != null) { Marshal.ReleaseComObject(nativeConditionFactory); } } return new SearchCondition(result); } */ /* /// <summary> /// Parses an input string that contains Structured Query keywords (using Advanced Query Syntax /// or Natural Query Syntax) and produces a SearchCondition object. /// </summary> /// <param name="query">The query to be parsed</param> /// <returns>Search condition resulting from the query</returns> /// <remarks>For more information on structured query syntax, visit http://msdn.microsoft.com/en-us/library/bb233500.aspx and /// http://www.microsoft.com/windows/products/winfamily/desktopsearch/technicalresources/advquery.mspx</remarks> public static SearchCondition ParseStructuredQuery(string query) { return ParseStructuredQuery(query, null); } */ /// <summary> /// Parses an input string that contains Structured Query keywords (using Advanced Query Syntax /// or Natural Query Syntax) and produces a SearchCondition object. /// </summary> /// <param name="query">The query to be parsed</param> /// <param name="cultureInfo">The culture used to select the localized language for keywords.</param> /// <returns>Search condition resulting from the query</returns> /// <remarks>For more information on structured query syntax, visit http://msdn.microsoft.com/en-us/library/bb233500.aspx and /// http://www.microsoft.com/windows/products/winfamily/desktopsearch/technicalresources/advquery.mspx</remarks> public static SearchCondition ParseStructuredQuery(string query, CultureInfo cultureInfo = null) { if (string.IsNullOrEmpty(query)) { throw new ArgumentNullException("query"); } IQueryParserManager nativeQueryParserManager = (IQueryParserManager)new QueryParserManagerCoClass(); IQueryParser queryParser = null; IQuerySolution querySolution = null; ICondition result = null; IEntity mainType = null; SearchCondition searchCondition = null; try { // First, try to create a new IQueryParser using IQueryParserManager Guid guid = new Guid(InterfaceGuids.IQueryParser); HResult hr = nativeQueryParserManager.CreateLoadedParser( "SystemIndex", cultureInfo == null ? (ushort)0 : (ushort)cultureInfo.LCID, ref guid, out queryParser); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } if (queryParser != null) { // If user specified natural query, set the option on the query parser using (PropVariant optionValue = new PropVariant(true)) { hr = queryParser.SetOption(StructuredQuerySingleOption.NaturalSyntax, optionValue); } if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } // Next, try to parse the query. // Result would be IQuerySolution that we can use for getting the ICondition and other // details about the parsed query. hr = queryParser.Parse(query, null, out querySolution); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } if (querySolution != null) { // Lastly, try to get the ICondition from this parsed query hr = querySolution.GetQuery(out result, out mainType); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } } } searchCondition = new SearchCondition(result); return searchCondition; } catch { if (searchCondition != null) searchCondition.Dispose(); throw; } finally { if (nativeQueryParserManager != null) { Marshal.ReleaseComObject(nativeQueryParserManager); } if (queryParser != null) { Marshal.ReleaseComObject(queryParser); } if (querySolution != null) { Marshal.ReleaseComObject(querySolution); } if (mainType != null) { Marshal.ReleaseComObject(mainType); } } }
/* * * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and constant value. * /// </summary> * /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. * /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> * /// <param name="value">The constant value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(string propertyName, string value, SearchConditionOperation operation) { * using (PropVariant propVar = new PropVariant(value)) { * return CreateLeafCondition(propertyName, propVar, null, operation); * } * } * * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and constant value. * /// Overload method takes a DateTime parameter for the comparison value. * /// </summary> * /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. * /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> * /// <param name="value">The DateTime value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(string propertyName, DateTime value, SearchConditionOperation operation) { * using (PropVariant propVar = new PropVariant(value)) { * return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.DateTime", operation); * } * } */ /* * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Integer value. * /// </summary> * /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. * /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> * /// <param name="value">The Integer value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(string propertyName, int value, SearchConditionOperation operation) { * using (PropVariant propVar = new PropVariant(value)) { * return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Integer", operation); * } * } */ /* * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Boolean value. * /// </summary> * /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. * /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> * /// <param name="value">The Boolean value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(string propertyName, bool value, SearchConditionOperation operation) { * using (PropVariant propVar = new PropVariant(value)) { * return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Boolean", operation); * } * } */ /* * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Floating Point value. * /// </summary> * /// <param name="propertyName">The name of a property to be compared, or null for an unspecified property. * /// The locale name of the leaf node is LOCALE_NAME_USER_DEFAULT.</param> * /// <param name="value">The Floating Point value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(string propertyName, double value, SearchConditionOperation operation) { * using (PropVariant propVar = new PropVariant(value)) { * return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.FloatingPoint", operation); * } * } */ /* * [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] * private static SearchCondition CreateLeafCondition(string propertyName, PropVariant propVar, string valueType, SearchConditionOperation operation) { * IConditionFactory nativeConditionFactory = null; * SearchCondition condition = null; * * try { * // Same as the native "IConditionFactory:MakeLeaf" method * nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); * * ICondition nativeCondition = null; * * if (string.IsNullOrEmpty(propertyName) || propertyName.ToUpperInvariant() == "SYSTEM.NULL") { * propertyName = null; * } * * HResult hr = HResult.S_FALSE; * * hr = nativeConditionFactory.MakeLeaf(propertyName, operation, valueType, * propVar, null, null, null, false, out nativeCondition); * * if (hr != HResult.S_OK) { * throw Marshal.GetExceptionForHR((int)hr); * } * * // Create our search condition and set the various properties. * condition = new SearchCondition(nativeCondition); * } * finally { * if (nativeConditionFactory != null) { * Marshal.ReleaseComObject(nativeConditionFactory); * } * } * * return condition; * } */ /* * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and constant value. * /// </summary> * /// <param name="propertyKey">The property to be compared.</param> * /// <param name="value">The constant value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, string value, SearchConditionOperation operation) { * string canonicalName; * PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); * * if (string.IsNullOrEmpty(canonicalName)) { * throw new ArgumentException("Invalid PK", "propertyKey"); * } * * return CreateLeafCondition(canonicalName, value, operation); * } */ /* * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and constant value. * /// Overload method takes a DateTime parameter for the comparison value. * /// </summary> * /// <param name="propertyKey">The property to be compared.</param> * /// <param name="value">The DateTime value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, DateTime value, SearchConditionOperation operation) { * string canonicalName; * PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); * * if (string.IsNullOrEmpty(canonicalName)) { * throw new ArgumentException("Invalid PK", "propertyKey"); * } * return CreateLeafCondition(canonicalName, value, operation); * } */ /* * * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Boolean value. * /// Overload method takes a DateTime parameter for the comparison value. * /// </summary> * /// <param name="propertyKey">The property to be compared.</param> * /// <param name="value">The boolean value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, bool value, SearchConditionOperation operation) { * string canonicalName; * PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); * * if (string.IsNullOrEmpty(canonicalName)) { * throw new ArgumentException("Invalid PK", "propertyKey"); * } * return CreateLeafCondition(canonicalName, value, operation); * } * * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Floating Point value. * /// Overload method takes a DateTime parameter for the comparison value. * /// </summary> * /// <param name="propertyKey">The property to be compared.</param> * /// <param name="value">The Floating Point value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, double value, SearchConditionOperation operation) { * string canonicalName; * PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); * * if (string.IsNullOrEmpty(canonicalName)) { * throw new ArgumentException("Invalid PK", "propertyKey"); * } * return CreateLeafCondition(canonicalName, value, operation); * } * * /// <summary> * /// Creates a leaf condition node that represents a comparison of property value and Integer value. * /// Overload method takes a DateTime parameter for the comparison value. * /// </summary> * /// <param name="propertyKey">The property to be compared.</param> * /// <param name="value">The Integer value against which the property value should be compared.</param> * /// <param name="operation">Specific condition to be used when comparing the actual value and the expected value of the given property</param> * /// <returns>SearchCondition based on the given parameters</returns> * /// <remarks> * /// The search will only work for files that are indexed, as well as the specific properties are indexed. To find * /// the properties that are indexed, look for the specific property's property description and * /// <see cref="P:Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyDescription.TypeFlags"/> property for IsQueryable flag. * /// </remarks> * public static SearchCondition CreateLeafCondition(PROPERTYKEY propertyKey, int value, SearchConditionOperation operation) { * string canonicalName; * PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out canonicalName); * * if (string.IsNullOrEmpty(canonicalName)) { * throw new ArgumentException("Invalid PK", "propertyKey"); * } * return CreateLeafCondition(canonicalName, value, operation); * } * * /// <summary> * /// Creates a condition node that is a logical conjunction ("AND") or disjunction ("OR") * /// of a collection of subconditions. * /// </summary> * /// <param name="conditionType">The SearchConditionType of the condition node. * /// Must be either AndCondition or OrCondition.</param> * /// <param name="simplify">TRUE to logically simplify the result, if possible; * /// then the result will not necessarily to be of the specified kind. FALSE if the result should * /// have exactly the prescribed structure. An application that plans to execute a query based on the * /// condition tree would typically benefit from setting this parameter to TRUE. </param> * /// <param name="conditionNodes">Array of subconditions</param> * /// <returns>New SearchCondition based on the operation</returns> * public static SearchCondition CreateAndOrCondition(SearchConditionType conditionType, bool simplify, params SearchCondition[] conditionNodes) { * // Same as the native "IConditionFactory:MakeAndOr" method * IConditionFactory nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); * ICondition result = null; * * try { * // * List<ICondition> conditionList = new List<ICondition>(); * if (conditionNodes != null) { * foreach (SearchCondition c in conditionNodes) { * conditionList.Add(c.NativeSearchCondition); * } * } * * IEnumUnknown subConditions = new EnumUnknownClass(conditionList.ToArray()); * * HResult hr = nativeConditionFactory.MakeAndOr(conditionType, subConditions, simplify, out result); * * if (hr != HResult.S_OK) { * throw Marshal.GetExceptionForHR((int)hr); * } * } * finally { * if (nativeConditionFactory != null) { * Marshal.ReleaseComObject(nativeConditionFactory); * } * } * * return new SearchCondition(result); * } * * /// <summary> * /// Creates a condition node that is a logical negation (NOT) of another condition * /// (a subnode of this node). * /// </summary> * /// <param name="conditionToBeNegated">SearchCondition node to be negated.</param> * /// <param name="simplify">True to logically simplify the result if possible; False otherwise. * /// In a query builder scenario, simplyfy should typically be set to false.</param> * /// <returns>New SearchCondition</returns> * public static SearchCondition CreateNotCondition(SearchCondition conditionToBeNegated, bool simplify) { * if (conditionToBeNegated == null) { * throw new ArgumentNullException("conditionToBeNegated"); * } * * // Same as the native "IConditionFactory:MakeNot" method * IConditionFactory nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass(); * ICondition result; * * try { * HResult hr = nativeConditionFactory.MakeNot(conditionToBeNegated.NativeSearchCondition, simplify, out result); * * if (hr != HResult.S_OK) { * throw Marshal.GetExceptionForHR((int)hr); * } * } * finally { * if (nativeConditionFactory != null) { * Marshal.ReleaseComObject(nativeConditionFactory); * } * } * * return new SearchCondition(result); * } * */ /* * /// <summary> * /// Parses an input string that contains Structured Query keywords (using Advanced Query Syntax * /// or Natural Query Syntax) and produces a SearchCondition object. * /// </summary> * /// <param name="query">The query to be parsed</param> * /// <returns>Search condition resulting from the query</returns> * /// <remarks>For more information on structured query syntax, visit http://msdn.microsoft.com/en-us/library/bb233500.aspx and * /// http://www.microsoft.com/windows/products/winfamily/desktopsearch/technicalresources/advquery.mspx</remarks> * public static SearchCondition ParseStructuredQuery(string query) { * return ParseStructuredQuery(query, null); * } */ /// <summary> /// Parses an input string that contains Structured Query keywords (using Advanced Query Syntax /// or Natural Query Syntax) and produces a SearchCondition object. /// </summary> /// <param name="query">The query to be parsed</param> /// <param name="cultureInfo">The culture used to select the localized language for keywords.</param> /// <returns>Search condition resulting from the query</returns> /// <remarks>For more information on structured query syntax, visit http://msdn.microsoft.com/en-us/library/bb233500.aspx and /// http://www.microsoft.com/windows/products/winfamily/desktopsearch/technicalresources/advquery.mspx</remarks> public static SearchCondition ParseStructuredQuery(string query, CultureInfo cultureInfo = null) { if (string.IsNullOrEmpty(query)) { throw new ArgumentNullException("query"); } IQueryParserManager nativeQueryParserManager = (IQueryParserManager) new QueryParserManagerCoClass(); IQueryParser queryParser = null; IQuerySolution querySolution = null; ICondition result = null; IEntity mainType = null; SearchCondition searchCondition = null; try { // First, try to create a new IQueryParser using IQueryParserManager Guid guid = new Guid(InterfaceGuids.IQueryParser); HResult hr = nativeQueryParserManager.CreateLoadedParser( "SystemIndex", cultureInfo == null ? (ushort)0 : (ushort)cultureInfo.LCID, ref guid, out queryParser); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } if (queryParser != null) { // If user specified natural query, set the option on the query parser using (PropVariant optionValue = new PropVariant(true)) { hr = queryParser.SetOption(StructuredQuerySingleOption.NaturalSyntax, optionValue); } if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } // Next, try to parse the query. // Result would be IQuerySolution that we can use for getting the ICondition and other // details about the parsed query. hr = queryParser.Parse(query, null, out querySolution); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } if (querySolution != null) { // Lastly, try to get the ICondition from this parsed query hr = querySolution.GetQuery(out result, out mainType); if (hr != HResult.S_OK) { throw Marshal.GetExceptionForHR((int)hr); } } } searchCondition = new SearchCondition(result); return(searchCondition); } catch { if (searchCondition != null) { searchCondition.Dispose(); } throw; } finally { if (nativeQueryParserManager != null) { Marshal.ReleaseComObject(nativeQueryParserManager); } if (queryParser != null) { Marshal.ReleaseComObject(queryParser); } if (querySolution != null) { Marshal.ReleaseComObject(querySolution); } if (mainType != null) { Marshal.ReleaseComObject(mainType); } } }