mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-30 10:19:51 +08:00
284 lines
9.8 KiB
C#
284 lines
9.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace MicaSetup.Shell.Dialogs;
|
|
|
|
public static class SearchConditionFactory
|
|
{
|
|
public static SearchCondition CreateAndOrCondition(SearchConditionType conditionType, bool simplify, params SearchCondition[] conditionNodes)
|
|
{
|
|
var nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass();
|
|
ICondition result = null!;
|
|
|
|
try
|
|
{
|
|
var conditionList = new List<ICondition>();
|
|
if (conditionNodes != null)
|
|
{
|
|
foreach (var c in conditionNodes)
|
|
{
|
|
conditionList.Add(c.NativeSearchCondition);
|
|
}
|
|
}
|
|
|
|
IEnumUnknown subConditions = new EnumUnknownClass(conditionList.ToArray());
|
|
|
|
var hr = nativeConditionFactory.MakeAndOr(conditionType, subConditions, simplify, out result);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); }
|
|
}
|
|
finally
|
|
{
|
|
if (nativeConditionFactory != null)
|
|
{
|
|
Marshal.ReleaseComObject(nativeConditionFactory);
|
|
}
|
|
}
|
|
|
|
return new SearchCondition(result);
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(string propertyName, string value, SearchConditionOperation operation)
|
|
{
|
|
using (var propVar = new PropVariant(value))
|
|
{
|
|
return CreateLeafCondition(propertyName, propVar, null!, operation);
|
|
}
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(string propertyName, DateTime value, SearchConditionOperation operation)
|
|
{
|
|
using (var propVar = new PropVariant(value))
|
|
{
|
|
return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.DateTime", operation);
|
|
}
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(string propertyName, int value, SearchConditionOperation operation)
|
|
{
|
|
using (var propVar = new PropVariant(value))
|
|
{
|
|
return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Integer", operation);
|
|
}
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(string propertyName, bool value, SearchConditionOperation operation)
|
|
{
|
|
using (var propVar = new PropVariant(value))
|
|
{
|
|
return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.Boolean", operation);
|
|
}
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(string propertyName, double value, SearchConditionOperation operation)
|
|
{
|
|
using (var propVar = new PropVariant(value))
|
|
{
|
|
return CreateLeafCondition(propertyName, propVar, "System.StructuredQuery.CustomProperty.FloatingPoint", operation);
|
|
}
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(PropertyKey propertyKey, string value, SearchConditionOperation operation)
|
|
{
|
|
PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out var canonicalName);
|
|
|
|
if (string.IsNullOrEmpty(canonicalName))
|
|
{
|
|
throw new ArgumentException(LocalizedMessages.SearchConditionFactoryInvalidProperty, "propertyKey");
|
|
}
|
|
|
|
return CreateLeafCondition(canonicalName, value, operation);
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(PropertyKey propertyKey, DateTime value, SearchConditionOperation operation)
|
|
{
|
|
PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out var canonicalName);
|
|
|
|
if (string.IsNullOrEmpty(canonicalName))
|
|
{
|
|
throw new ArgumentException(LocalizedMessages.SearchConditionFactoryInvalidProperty, "propertyKey");
|
|
}
|
|
return CreateLeafCondition(canonicalName, value, operation);
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(PropertyKey propertyKey, bool value, SearchConditionOperation operation)
|
|
{
|
|
PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out var canonicalName);
|
|
|
|
if (string.IsNullOrEmpty(canonicalName))
|
|
{
|
|
throw new ArgumentException(LocalizedMessages.SearchConditionFactoryInvalidProperty, "propertyKey");
|
|
}
|
|
return CreateLeafCondition(canonicalName, value, operation);
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(PropertyKey propertyKey, double value, SearchConditionOperation operation)
|
|
{
|
|
PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out var canonicalName);
|
|
|
|
if (string.IsNullOrEmpty(canonicalName))
|
|
{
|
|
throw new ArgumentException(LocalizedMessages.SearchConditionFactoryInvalidProperty, "propertyKey");
|
|
}
|
|
return CreateLeafCondition(canonicalName, value, operation);
|
|
}
|
|
|
|
public static SearchCondition CreateLeafCondition(PropertyKey propertyKey, int value, SearchConditionOperation operation)
|
|
{
|
|
PropertySystemNativeMethods.PSGetNameFromPropertyKey(ref propertyKey, out var canonicalName);
|
|
|
|
if (string.IsNullOrEmpty(canonicalName))
|
|
{
|
|
throw new ArgumentException(LocalizedMessages.SearchConditionFactoryInvalidProperty, "propertyKey");
|
|
}
|
|
return CreateLeafCondition(canonicalName, value, operation);
|
|
}
|
|
|
|
public static SearchCondition CreateNotCondition(SearchCondition conditionToBeNegated, bool simplify)
|
|
{
|
|
if (conditionToBeNegated == null)
|
|
{
|
|
throw new ArgumentNullException("conditionToBeNegated");
|
|
}
|
|
|
|
var nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass();
|
|
ICondition result;
|
|
|
|
try
|
|
{
|
|
var hr = nativeConditionFactory.MakeNot(conditionToBeNegated.NativeSearchCondition, simplify, out result);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); }
|
|
}
|
|
finally
|
|
{
|
|
if (nativeConditionFactory != null)
|
|
{
|
|
Marshal.ReleaseComObject(nativeConditionFactory);
|
|
}
|
|
}
|
|
|
|
return new SearchCondition(result);
|
|
}
|
|
|
|
public static SearchCondition ParseStructuredQuery(string query) => ParseStructuredQuery(query, null!);
|
|
|
|
public static SearchCondition ParseStructuredQuery(string query, CultureInfo cultureInfo)
|
|
{
|
|
if (string.IsNullOrEmpty(query))
|
|
{
|
|
throw new ArgumentNullException("query");
|
|
}
|
|
|
|
var nativeQueryParserManager = (IQueryParserManager)new QueryParserManagerCoClass();
|
|
IQueryParser queryParser = null!;
|
|
IQuerySolution querySolution = null!;
|
|
ICondition result = null!;
|
|
|
|
IEntity mainType = null!;
|
|
SearchCondition searchCondition = null!;
|
|
try
|
|
{
|
|
var guid = new Guid(ShellIIDGuid.IQueryParser);
|
|
var hr = nativeQueryParserManager.CreateLoadedParser(
|
|
"SystemIndex",
|
|
cultureInfo == null ? (ushort)0 : (ushort)cultureInfo.LCID,
|
|
ref guid,
|
|
out queryParser);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); }
|
|
|
|
if (queryParser != null)
|
|
{
|
|
using (var optionValue = new PropVariant(true))
|
|
{
|
|
hr = queryParser.SetOption(StructuredQuerySingleOption.NaturalSyntax, optionValue);
|
|
}
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); }
|
|
|
|
hr = queryParser.Parse(query, null!, out querySolution);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); }
|
|
|
|
if (querySolution != null)
|
|
{
|
|
hr = querySolution.GetQuery(out result, out mainType);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(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);
|
|
}
|
|
}
|
|
}
|
|
|
|
[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
|
|
{
|
|
nativeConditionFactory = (IConditionFactory)new ConditionFactoryCoClass();
|
|
|
|
if (string.IsNullOrEmpty(propertyName) || propertyName.ToUpperInvariant() == "SYSTEM.NULL")
|
|
{
|
|
propertyName = null!;
|
|
}
|
|
|
|
var hr = HResult.Fail;
|
|
|
|
hr = nativeConditionFactory.MakeLeaf(propertyName, operation, valueType,
|
|
propVar, null!, null!, null!, false, out var nativeCondition);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr))
|
|
{
|
|
throw new ShellException(hr);
|
|
}
|
|
|
|
condition = new SearchCondition(nativeCondition);
|
|
}
|
|
finally
|
|
{
|
|
if (nativeConditionFactory != null)
|
|
{
|
|
Marshal.ReleaseComObject(nativeConditionFactory);
|
|
}
|
|
}
|
|
|
|
return condition;
|
|
}
|
|
}
|