Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C Offreg.dll“System.AccessViolationException”ORGetValue_C#_Winapi_Registry - Fatal编程技术网

C# C Offreg.dll“System.AccessViolationException”ORGetValue

C# C Offreg.dll“System.AccessViolationException”ORGetValue,c#,winapi,registry,C#,Winapi,Registry,我试图从脱机配置单元中包含的注册表项中获取值。代码可以编译,但我得到'System.AccessViolationException',或者程序刚刚关闭 我认为程序正在尝试读取或写入未分配的内存。但是,我尝试使用stringbuilder为myValue分配内存 当我将pcbData设置为低于66的任何值时,我得到的返回值为234,这意味着指定的缓冲区大小不足以容纳数据 OROpenHive似乎正在工作,因为我得到的返回值为0 ORGetValue的语法位于 这是我的密码: [DllIm

我试图从脱机配置单元中包含的注册表项中获取值。代码可以编译,但我得到'System.AccessViolationException',或者程序刚刚关闭

我认为程序正在尝试读取或写入未分配的内存。但是,我尝试使用stringbuilder为myValue分配内存

当我将pcbData设置为低于66的任何值时,我得到的返回值为234,这意味着指定的缓冲区大小不足以容纳数据

OROpenHive似乎正在工作,因为我得到的返回值为0

ORGetValue的语法位于

这是我的密码:

    [DllImport("offreg.dll", CharSet = CharSet.Auto, EntryPoint = "ORGetValue",          SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    public static extern uint ORGetValue(
        IntPtr Handle, 
        string lpSubKey, 
        string lpValue, 
        out uint pdwType, 
        out StringBuilder pvData, 
        ref uint pcbData);

    [DllImport("offreg.dll", CharSet = CharSet.Auto)]
    public static extern uint OROpenHive(
        String lpHivePath,
        out IntPtr phkResult);

    private void button2_Click(object sender, EventArgs e)
    {
        IntPtr myHive;
        String filepath = @"C:\Users\JON\Desktop\NTUSER.DAT";

        StringBuilder myValue = new StringBuilder("", 256);
        uint pdwtype;
        uint pcbdata = 66;

        uint ret2 = OROpenHive(filepath, out myHive);
        this.textBox1.Text = ret2.ToString();

        uint ret3 = ORGetValue(myHive, "Environment", "TEMP", out pdwtype, out myValue,  ref pcbdata);
        this.textBox1.Text = ret3.ToString();
    }

你把结果搞错了。pcbdata应该以缓冲区的大小传递,它将包含函数返回后读取的实际字符数

Winapi函数不知道缓冲区的大小,所以即使分配256个字节,也会告诉ORGetValue您只分配了66个。。。如果您正在读取一个需要超过66字节的密钥,它将返回234或ERROR\u more\u数据

您通常会执行以下操作:

StringBuilder myValue = new StringBuilder("", 256);
uint pcbdata = myValue.Capacity;
//...
uint ret3 = ORGetValue(myHive, "Environment", "TEMP", out pdwtype, out myValue,  ref pcbdata);
this.textBox1.Text = "Read " + pcbdata.ToString() + " bytes - returned: " + ret3.ToString();

如果您的密钥是66字节,那么应该是:read 66字节-返回:0

我肯定缺少什么。Visual Basic不允许uint pcbdata=myValue.Capacity;基本上为返回的字符串分配256个字节,但告诉函数您只分配了66个字节,因此函数认为缓冲区只有66个字节长。如果它需要超过66个字节,它会抱怨。对不起,我弄错了编辑按钮。我想说的是这个。Visual Basic不允许uint pcbdata=myValue.Capacity;我一直在获取不可开票的成员“System.Text.StringBuilder.Capacity”不能像方法一样使用。即使将pcbdata的值更改为256,我仍然获取System.AccessViolationException.噢,抱歉,没有看到:尝试不要在StringBuilder参数上使用out。。。返回时您不会得到StringBuilder,而是填写您传入的StringBuilder。删除定义和调用上的out
StringBuilder myValue = new StringBuilder("", 256);
uint pcbdata = myValue.Capacity;
//...
uint ret3 = ORGetValue(myHive, "Environment", "TEMP", out pdwtype, out myValue,  ref pcbdata);
this.textBox1.Text = "Read " + pcbdata.ToString() + " bytes - returned: " + ret3.ToString();