C#Interop:值不在预期范围内

时间:2019-05-31 03:45:16

标签: c# com com-interop

我正在编写一个c#程序来访问“窗口文件历史记录”系统中的设置。由于找不到dll(fhcfg.dll)的COM包装器,因此我尝试编写自己的......我几乎没有做任何互操作编程。

我正在按照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.h中的定义定义了这些,并用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);
    }
}

junk.GetLocalPolicy()行引发ArgumentException(“值不在预期范围内”)。

除了想了解导致我得到异常的原因之外,我还想学习一种更简单/更简单的方法来处理没有预定义类型lib时访问非托管代码的情况。

跟进

感谢提供的大量反馈,我能够使代码正常工作。

为了他人的利益,代码中还潜伏着第二个问题:必须先在接口上调用LoadConfiguration(),然后GetLocalPolicy()才能成功(即,GetLocalPolicy()在该对象的“隐藏”实例上工作)配置对象,您必须先加载它。)

不过,我确实有一些后续问题:

  • 在c#中定义COM接口时,它是按位置完成的- 接口定义中的方法1必须与声明中的方法1相匹配 C ++头文件-还是按名称完成?我以为是 名称,但答案(对我而言)似乎暗示其他含义。
  • 如果c ++方法声明包含单个[out]参数,则c#可以 接口方法以该参数声明为方法的 返回值,还是需要将其声明为out参数?

顺便说一句,我还要感谢汉斯·帕桑特(Hans Passant)的有用的回答/解释……我很乐意接受“答案”,但它似乎已消失了。

0 个答案:

没有答案