Я пишу ac # программу для доступа к настройкам из системы Window File History.Так как я не смог найти оболочку COM для dll (fhcfg.dll), я пытаюсь написать свой собственный ... и я почти не занимался программированием взаимодействия.
Я следую инструкциямв https://msdn.microsoft.com/en-us/ie/aa645736%28v=vs.94%29?f=255&MSPPError=-2147217396.
Вот определения классов и интерфейсов, которые я написал (GUID взяты из FhCfg.h):
[ComImport, Guid("ED43BB3C-09E9-498a-9DF6-2177244C6DB4")]
public class FHManager
{
}
[ Guid( "6A5FEA5B-BF8F-4EE5-B8C3-44D8A0D7331C" ), InterfaceType( ComInterfaceType.InterfaceIsDual ) ]
public interface IFHManager
{
void LoadConfiguration();
void CreateDefaultConfiguration( [ In ] bool overwriteIfExists );
void SaveConfiguration();
void AddRemoveExcludeRule(
[ In ] bool add,
[ In ] ProtectedItemCategory category,
[ Out, MarshalAs( UnmanagedType.BStr ) ]
string item
);
void GetIncludeExcludeRules(
[ In ] bool include,
[ In ] ProtectedItemCategory category,
[ Out ] IntPtr iterator
);
void GetLocalPolicy(
[ In ] LocalPolicy localPolicy,
[ Out ] ulong policyValue
);
void SetLocalPolicy(
[ In ] LocalPolicy localPolicy,
[ In ] ulong policyValue
);
void GetBackupStatus( [ Out ] BackupStatus status );
void SetBackupStatus( [ In ] BackupStatus status );
void GetDefaultTarget( [ Out ] IntPtr target );
void ValidateTarget( [ In, MarshalAs( UnmanagedType.BStr ) ]
string url, [ Out ] ValidationResult validationResult );
void ProvisionAndSetNewTarget(
[ In, MarshalAs( UnmanagedType.BStr ) ]
string url,
[ In, MarshalAs( UnmanagedType.BStr ) ]
string name
);
void ChangeDefaultTargetRecommendation( [ In ] bool recommend );
void QueryProtectionStatus(
[ Out ] int protectionState,
[ Out, MarshalAs( UnmanagedType.BStr ) ]
string protectedUntilTime
);
}
Я определил их на основе определений в FhCfg.ч, с парой замен IntPtrs для указателей на итераторы (с которыми я не уверен, как правильно обращаться, но так как я не использую эти методы, я решил, что это не имеет значения).
Единственный метод, который мне сейчас интересен, - это GetLocalPolicy ().
Различные перечисления, которые я только что переписал в c #, при условии, что в c ++ и c # они будут по умолчанию основаны на int.
Код, который я использую для упражнения GetLocalPolicy (), представляет собой консольное приложение Net Core:
class Program
{
static void Main(string[] args)
{
FHManager fhm = new FHManager();
var junk = fhm as IFHManager;
ulong value = 0;
junk.GetLocalPolicy( LocalPolicy.Frequency, value);
}
}
Исключение ArgumentException («Значение не попадает в ожидаемый диапазон») выбрасывается нежелательной.GetLocalPolicy () line.
В дополнение к желаниюЧтобы понять, что вызывает исключение, которое я получаю, мне было бы интересно узнать о более простом и более надежном способе доступа к неуправляемому коду, когда нет предопределенного типа lib.
Followup
Спасибо за отличную обратную связь, при условии, что мне удалось заставить код работать.
Для пользы других в коде скрывалась вторая проблема: вы должнывызовите LoadConfiguration () на интерфейсе до того, как GetLocalPolicy () сможет завершиться успешно (т. е. GetLocalPolicy () работает с «скрытым» экземпляром объекта конфигурации, который вы должны загрузить в первую очередь).
У меня действительно есть продолжениевопросы:
- При определении интерфейса COM в c # выполняется ли это позиционно - метод 1 в определении интерфейса должен соответствовать методу 1, объявленному в заголовочном файле c ++, или это делаетсяназвание?Я предполагал, что это было по имени, но ответ (для меня), кажется, подразумевает иное.
- Если объявление метода c ++ содержит единственный параметр [out], может ли интерфейсный интерфейс c # быть объявлен с этим параметром каквозвращаемое значение метода, или вам нужно объявить его как выходной параметр?
Кстати, я также хотел бы поблагодарить Ханса Пассанта за его полезный ответ / объяснение ... что я бы с радостьюпримите как «ответ», за исключением того, что он, кажется, исчез.