3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
1
.NET 4.x

Не отлавливаемое исключение при использовании неуправляемого кода

29.05.2016, 22:52. Показов 640. Ответов 11
Метки нет (Все метки)

Пытаюсь получить параметры ключа реестра через вызов RegEnumValue

Импортировал так
C#
1
2
3
4
5
6
7
8
9
10
 [DllImport("advapi32.dll", EntryPoint = "RegEnumValue")]
  public static extern int RegEnumValueA(
           UIntPtr hKey,
           int dwIndex,
           out string lpValueName,
           out int lpcbValueName,
           int lpReserved,
           out int lpType,
           out IntPtr lpData,
           out int lpcbData);
Использовал так

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
              
                        int lpcbValueName = 1024, lpType, lpcbData = 1024;
                        IntPtr lpData = Marshal.AllocHGlobal(1024);
                        string lpValueName = "";
                        for (int i = 0; i < ValueCount; i++)
                        {
                            int ValueError = RegEnumValueA(
                                OpenKey,
                                i,
                                out lpValueName,
                                out lpcbValueName,
                                0,
                                out lpType,
                                out lpData,
                                out lpcbData);
                            string dt = Marshal.PtrToStringUni(lpData);
                        }
При проходе отладчиком, без каких либо сообщений программа завершается. Единственное, что намекает на проблему-строка в окне вывода Visual Studio.
Вызвано исключение: "System.AccessViolationException" в mscorlib.dll
Программа "[9932] CursProject.vshost.exe" завершилась с кодом -1073741819 (0xc0000005) 'Access violation'.

Каким образом отловить исключение или исправить ошибку?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.05.2016, 22:52
Ответы с готовыми решениями:

Исключение при использовании алгоритма
Добрый день, помогите разобраться с исключением: Необработанное исключение по адресу...

Исключение при использовании API КЛАДР
Здравствуйте. Не очень, к сожалению силен в потоках, коллбэках и т.п. Понадобилось мне...

Unhandled исключение при использовании NAudio
Я написал ВПФ приложение-Медиа Плеер с использованием библиотеки НАудио. Когда я хочу...

Запуск неуправляемого кода внутри кода c#
часто требуется при выполнении программы запускать исполняемые файлы (exe) с ключами. Для этого...

11
Эксперт .NET
6269 / 3897 / 1567
Регистрация: 09.05.2015
Сообщений: 9,188
30.05.2016, 00:26 2
http://www.pinvoke.net/default... genumvalue
0
3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
30.05.2016, 20:28  [ТС] 3
Ок, исправил сигнатуру, выдает ERROR_INVALID_PARAMETER. В каком из них может быть проблема?
C#
1
2
3
4
5
6
7
8
9
10
[DllImport("advapi32.dll", EntryPoint = "RegEnumValue",SetLastError = true)]
        static extern uint RegEnumValue(
         IntPtr hKey,
         uint dwIndex,
         StringBuilder lpValueName,
         ref uint lpcValueName,
         IntPtr lpReserved,
         IntPtr lpType,
         IntPtr lpData,
         IntPtr lpcbData);
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 if (ValueCount > 0)
                {
                    IntPtr lpType = Marshal.AllocHGlobal(4);
                    IntPtr lpcbData = Marshal.AllocHGlobal(4);
                    IntPtr lpReserved = Marshal.AllocHGlobal(4);
                    Marshal.WriteInt32(lpType,0);
                    Marshal.WriteInt32(lpcbData, 1024);
                    Marshal.WriteInt32(lpReserved, 0);
                    IntPtr lpData = Marshal.AllocHGlobal(1024);
                    uint lpcbValueName = 1024;
                    StringBuilder lpValueName=new StringBuilder("");
                        for (int i = 0; i < ValueCount; i++)
                        {
                      
                            uint ValueError = RegEnumValue(
                                OpenKey,
                                (uint)i,
                                lpValueName,
                                ref lpcbValueName,
                                lpReserved,
                                lpType,
                                lpData,
                                lpcbData);
                            string dt = Marshal.PtrToStringAnsi(lpData);                     
                    }
                    
                    }
0
Эксперт .NET
16745 / 12496 / 3285
Регистрация: 17.09.2011
Сообщений: 20,727
30.05.2016, 21:44 4
Цитата Сообщение от Life Crusher Посмотреть сообщение
StringBuilder lpValueName=new StringBuilder("");
Вы передаете пустой буфер, маршаллится он как указатель на строку и неуправляемый код ничего не знает о внутренней реализации объекта.
Создайте буфер по-больше и его передавайте:
C#
1
StringBuilder lpValueName=new StringBuilder(256);
0
3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
30.05.2016, 22:20  [ТС] 5
Тот же результат
0
Эксперт .NET
6269 / 3897 / 1567
Регистрация: 09.05.2015
Сообщений: 9,188
30.05.2016, 22:35 6
Вам последние 4 параметра точно нужны? Вместо них можно IntPtr.Zero передавать.
0
3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
30.05.2016, 22:50  [ТС] 7
Да, мне нужно получить значение параметра реестра и его тип.
0
Эксперт .NET
6269 / 3897 / 1567
Регистрация: 09.05.2015
Сообщений: 9,188
30.05.2016, 23:41 8
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
        [DllImport("advapi32.dll", EntryPoint = "RegEnumValue", SetLastError = true)]
        static extern uint RegEnumValue(
         IntPtr hKey,
         int dwIndex,
         IntPtr lpValueName,
         ref int lpcValueName,
         IntPtr lpReserved,
         out int lpType,
         IntPtr lpData,
         out int lpcbData);
 
            IntPtr hReg = Registry.LocalMachine.Handle.DangerousGetHandle();
 
            int valueType, valueNameSize, dataSize;
 
            IntPtr valueName = Marshal.AllocHGlobal(1024);
            IntPtr data = Marshal.AllocHGlobal(1024);
 
            int valuesCount = 5;
 
            for(int i = 0; i < valuesCount; i++)
            {
                valueNameSize = 1024;
                dataSize = 1024;
 
                uint retval = RegEnumValue(hReg, i, valueName, ref valueNameSize, IntPtr.Zero, out valueType, data, out dataSize);
 
                if (retval == 0)
                {
                    /*
                    #define REG_NONE                    ( 0 )   // No value type
                    #define REG_SZ                      ( 1 )   // Unicode nul terminated string
                    #define REG_EXPAND_SZ               ( 2 )   // Unicode nul terminated string
                                                                // (with environment variable references)
                    #define REG_BINARY                  ( 3 )   // Free form binary
                    #define REG_DWORD                   ( 4 )   // 32-bit number
                    #define REG_DWORD_LITTLE_ENDIAN     ( 4 )   // 32-bit number (same as REG_DWORD)
                    #define REG_DWORD_BIG_ENDIAN        ( 5 )   // 32-bit number
                    #define REG_LINK                    ( 6 )   // Symbolic Link (unicode)
                    #define REG_MULTI_SZ                ( 7 )   // Multiple Unicode strings
                    #define REG_RESOURCE_LIST           ( 8 )   // Resource list in the resource map
                    #define REG_FULL_RESOURCE_DESCRIPTOR ( 9 )  // Resource list in the hardware description
                    #define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )
                    #define REG_QWORD                   ( 11 )  // 64-bit number
                    #define REG_QWORD_LITTLE_ENDIAN     ( 11 )  // 64-bit number (same as REG_QWORD)
                    */
                    string name = Marshal.PtrToStringAnsi(valueName, valueNameSize);
 
                    if (valueType == 1) // REG_SZ
                    {
                        string val = Marshal.PtrToStringAnsi(data, dataSize);
 
                        Debug.WriteLine("type {0}, name {1}, value {2}", valueType, name, val);
                    }
                    else if(valueType == 4) // REG_DWORD
                    {
                        int val = Marshal.ReadInt32(data);
 
                        Debug.WriteLine("type {0}, name {1}, value {2}", valueType, name, val);
                    }
                    else if (valueType == 11) // REG_QWORD
                    {
                        long val = Marshal.ReadInt64(data);
 
                        Debug.WriteLine("type {0}, name {1}, value {2}", valueType, name, val);
                    }
                    else
                    {
                        Debug.WriteLine("type {0}, name {1}", valueType, name);
                    }
                }
            }
 
            Marshal.FreeHGlobal(valueName);
            Marshal.FreeHGlobal(data);
0
Эксперт .NET
16745 / 12496 / 3285
Регистрация: 17.09.2011
Сообщений: 20,727
30.05.2016, 23:54 9
Цитата Сообщение от Life Crusher Посмотреть сообщение
мне нужно получить значение параметра реестра и его тип.
А чем не устраивают стандартные классы для работы с реестром, имеющиеся в .NET?
1
3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
31.05.2016, 00:16  [ТС] 10
Нужно сделать экспорт заданных ключей реестра в один файл. Классы .Net вроде не позволяют получить список названий параметров ключа, чтобы обратится к ним по именам, и не позволяют обращаться к ним по индексу. Пытаюсь с помощью WinApi получить все подключи и параметры ключей, чтобы записать их в reg файл.
0
Эксперт .NET
6269 / 3897 / 1567
Регистрация: 09.05.2015
Сообщений: 9,188
31.05.2016, 00:25 11
Ну как это не позволяют? RegistryKey.GetSubKeyNames, RegistryKey.GetValueNames...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            var lm = Registry.LocalMachine;
 
            var subKeys = lm.GetSubKeyNames();
 
            var values = lm.GetValueNames();
 
            foreach (var name in subKeys)
            {
                Debug.WriteLine(string.Format("subkey: name {0}", name));
            }
 
            foreach (var name in values)
            {
                Debug.WriteLine("value: type {0}, name {1}, value {2}", lm.GetValueKind(name), name, lm.GetValue(name));
            }
1
3 / 3 / 1
Регистрация: 27.12.2013
Сообщений: 77
31.05.2016, 00:44  [ТС] 12
Да, вроде просмотрел еще раз MSDN и все нашлось. Просто когда задавал тут же этот вопрос, сказали использовать функции WinAPI. Спасибо за наводку, избавили от гемороя
Миниатюры
Не отлавливаемое исключение при использовании неуправляемого кода  
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.05.2016, 00:44
Помогаю со студенческими работами здесь

Исключение времени выполнения при использовании ADO
Добрый день. Внизу привёл код. Компилируется без проблем. А вот при выполнении выкидывает...

Необработанное исключение при использовании двумерного массива структуры
Вновь приветствую вас, вот у меня возникла такая проблема, При попытки использовать двумерный...

опасности неуправляемого кода
какие опасности несет в себе неуправляемый код. На ум приходит только назначение переменным...

Подключение неуправляемого кода
Есть код на С++ struct auth_answer{ int TType; /**&lt; тип транзакции. см...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru