powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
11 сообщений из 11, страница 1 из 1
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834792
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно ситуация примерно как здесь:
Сохранение цвета текста выделенных и hover-итемов в ListView (стиль Explorer)
Хотя вещи совершенно разные.
VS2013 EE VB.Net на Win8.1
Net 4.5 (дефолт) -работает
Конвертирую в Net2(3.5 и т.п.) -глючит, обратная конвертация проекта в 4.5 уже не помогает.

Код (урезанный, но достаточный для воспроизведения бага):
Код: vbnet
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.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
Imports System.Runtime.InteropServices

Module Module1
  'System-Defined Device Interface Classes
  ' Device Interface Classes for Modem Devices
  Public Const GUID_DEVINTERFACE_MODEM As String = _
   "{2C7089AA-2E0E-11D1-B114-00C04FC2AAE4}"

  Private Const S_OK = 0

  Private Const INVALID_HANDLE_VALUE = -1
  Private Const ERROR_NO_MORE_ITEMS = 259

  'COM Fundamentals Functions
  Public Declare Unicode Function IIDFromString Lib "ole32.dll" _
   (ByVal lpsz As String, ByRef lpiid As Guid) As Integer

  'Device Installation Structures
  <StructLayout(LayoutKind.Sequential)>
  Public Structure SP_DEVINFO_DATA
    Dim cbSize As Integer
    Dim ClassGuid As Guid
    Dim DevInst As IntPtr
    Dim Reserved As IntPtr
  End Structure

  'Public Device Installation Functions

  Public Declare Function SetupDiDestroyDeviceInfoList Lib "setupapi.dll" _
   (ByVal DeviceInfoSet As IntPtr) As Boolean

  Public Declare Function SetupDiEnumDeviceInfo Lib "setupapi.dll" _
   (ByVal DeviceInfoSet As IntPtr, _
   ByVal MemberIndex As Integer, _
   ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean

  'Flags - specifies control options that filter the device information elements that are added to the device information set
  Public Const DIGCF_PRESENT = &H2
  Public Const DIGCF_ALLCLASSES = &H4
  Public Const DIGCF_PROFILE = &H8
  Public Const DIGCF_DEVICEINTERFACE = &H10

  Public Declare Unicode Function SetupDiGetClassDevs _
   Lib "setupapi.dll" Alias "SetupDiGetClassDevsW" _
   (ByRef ClassGuid As Guid, _
   ByVal Enumerator As String, _
   ByVal hWndParent As IntPtr, _
   ByVal flags As Integer) As IntPtr

  Public Function RaiseAPIErrorByNumber(ByVal ErrNum As Integer) As String
    Return ErrNum.ToString & " (" & (New System.ComponentModel.Win32Exception(ErrNum)).Message & ")"
  End Function


  Public Sub GetModemsListFromClsid()
    Dim dwRes As Integer
    Dim m_ClassGUID As Guid
    Dim hDeviceInfoSet As IntPtr
    Dim bResult As Boolean
    Dim wIndex As Integer
    Dim m_DeviceInfoData As SP_DEVINFO_DATA

    'enum-ератор на основании GUID_DEVINTERFACE_MODEM
    'можно CLSIDFromString вместо IIDFromString -пофиг
    dwRes = IIDFromString(GUID_DEVINTERFACE_MODEM, m_ClassGUID)
    If dwRes <> S_OK Then
      Debug.Print("IIDFromString Error " & RaiseAPIErrorByNumber(dwRes))
      Exit Sub
    End If

    'DIGCF_DEVICEINTERFACE для этого m_ClassGUID -существенно!!!
    hDeviceInfoSet = SetupDiGetClassDevs(m_ClassGUID, vbNullString, 0, _
     DIGCF_PROFILE Or DIGCF_DEVICEINTERFACE) 'DIGCF_PRESENT Or
    If hDeviceInfoSet = INVALID_HANDLE_VALUE Then
      Debug.Print("SetupDiGetClassDevs Error " & RaiseAPIErrorByNumber(Err.LastDllError))
    Else
      Debug.Print("hDeviceInfoSet=" & hDeviceInfoSet.ToString)
      wIndex = 0
      m_DeviceInfoData.cbSize = Marshal.SizeOf(m_DeviceInfoData)
      Debug.Print("m_DeviceInfoData.cbSize=" & m_DeviceInfoData.cbSize)
      Do
        bResult = SetupDiEnumDeviceInfo(hDeviceInfoSet, wIndex, m_DeviceInfoData)
        If (bResult = False) And (Err.LastDllError = ERROR_NO_MORE_ITEMS) Then Exit Do
        If Err.LastDllError = 0 Then
          Debug.Print("wIndex=" & wIndex.ToString & " m_DeviceInfoData=" & m_DeviceInfoData.DevInst.ToString)
        Else
          Debug.Print("Err.LastDllError=" & RaiseAPIErrorByNumber(Err.LastDllError))
        End If
        wIndex = wIndex + 1
      Loop

      SetupDiDestroyDeviceInfoList(hDeviceInfoSet)
    End If

  End Sub

End Module



В .Net 4.5 работает (находит 5 модемов, DevInst 1-5), дебаг дает:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
hDeviceInfoSet=12693760
m_DeviceInfoData.cbSize=28
wIndex=0 DevInst=1
wIndex=1 DevInst=2
wIndex=2 DevInst=3
wIndex=3 DevInst=4
wIndex=4 DevInst=5



После конвертации проекта в .Net2 - не работает,
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
hDeviceInfoSet=463398784
m_DeviceInfoData.cbSize=40
Err.LastDllError=1784 (Имеющийся буфер не подходит для указанной операции)
Err.LastDllError=1784 (Имеющийся буфер не подходит для указанной операции)
Err.LastDllError=1784 (Имеющийся буфер не подходит для указанной операции)
Err.LastDllError=1784 (Имеющийся буфер не подходит для указанной операции)
Err.LastDllError=1784 (Имеющийся буфер не подходит для указанной операции)


и меня уже очень смущает уже
Marshal.SizeOf(m_DeviceInfoData) =40 (вместо 28)
При этом подтасовка m_DeviceInfoData.cbSize =28 все равно выводит ошибку про буфер.

А если этот .Net2-конвертированный проект компильнуть и сунуть на XP, то все работает.

Я этого не понимаю, ощущение (этот пост и предыдущий) что наступаю на одни и те же грабли.
Глючит на .Net2 скорее всего этот ваш Marshall.
Предполагаю, что я что-то "не дописываю", что на .Net 4.5 проходит по дефолту, а на .Net2 (после конвертации) надо указать явно (м.б.какие-то слова при опеделении структур, но Юникода в этих структурах нет). М.б. что то путаю с Integer/IntPtr, но полагаю и то и другое 4 байта.

Тест -Проект .Net4.5 (рабочий - дефолтный не "порченный") прилагаю.
Чтоб дебаг чего-то выводил, надо чтоб на компе был хотя б один модем.
Но можно то же воспроизвести и с портами:
Код: vbnet
1.
2.
3.
4.
5.
6.
  Public Const GUID_DEVINTERFACE_MODEM As String = _
   "{2C7089AA-2E0E-11D1-B114-00C04FC2AAE4}"
  Public Const GUID_DEVINTERFACE_COMPORT As String = _
   "{86E0D1E0-8089-11D0-9CE4-08003E301F73}"
  Public Const GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR As String = _
   "{4D36E978-E325-11CE-BFC1-08002BE10318}"
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834842
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77
Код: vbnet
1.
Dim DevInst As IntPtr



вообще-то это DWORD
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834858
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дас, наверно надо аккуратнее
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
  'Device Installation Structures
  <StructLayout(LayoutKind.Sequential)>
  Public Structure SP_DEVINFO_DATA
    Dim cbSize As Integer
    Dim ClassGuid As Guid
    Dim DevInst As IntPtr
    Dim Reserved As IntPtr
  End Structure



Странно, в .Net 4.5
Marshal.SizeOf(New IntPtr) =4,
а после конвертации проекта в .Net2
Marshal.SizeOf(New IntPtr) =8, хотя откуда 40 все равно не догоняю или невнимателен, 2*(8-4)= +8 (а не 12)

Привык я к As Long в VB6 вместо всего подряд, и муваю все это в Integer/Int32/IntPtr по сути как в голову взбредет (типа по смыслу).
Наверно неправ.
SP_DEVINFO_DATA structure

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//С++
typedef struct _SP_DEVINFO_DATA {
  DWORD     cbSize;
  GUID      ClassGuid;
  DWORD     DevInst;
  ULONG_PTR Reserved;
} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;



Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
  'Device Installation Structures
  <StructLayout(LayoutKind.Sequential)>
  Public Structure SP_DEVINFO_DATA
    Dim cbSize As Integer
    Dim ClassGuid As Guid
    Dim DevInst As Integer
    Dim Reserved As UIntPtr
  End Structure


Так заработало "везде одинаково".
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834896
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

размер IntPtr зависит от разрядности приложения 32 vs 64

в сокетах есть структуры вообще с разным лэйаутом для 32 и 64
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834931
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилразмер IntPtr зависит от разрядности приложения 32 vs 64
Ну, в VB.Net 2013 "Any CPU" -должно устраивать, почему нет.
Только при конвертации .Net 4.5 в .Net2 в этой же студии почему-то IntPtr размер прыгает с 4 до 8 байт - на том же самом Win 8.1 x64. И при обратной конвертации в .Net 4.5 назад к 4 байтам не прыгает
А при переносе этого exe-шника .Net2 на XP все опять работает.

Да не я понимаю что все управляется "внешней шарашкой", но однако ж бардак.
Не, в скелетиках может и интересно копаться, но копаться в скелетиках .Net честно желания нет.
Сказано "Any CPU" -звучит красиво, меня устраивает.
Ну, принципы главное понять, чего можно писать, а чего нельзя. Пока грабель не наломаешь, видимо не утрясется.
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38834941
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Сказано "Any CPU" -звучит красиво, меня устраивает.
только не можешь предсказать 4 или 8 байт будет IntPtr
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38835006
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилтолько не можешь предсказать 4 или 8 байт будет IntPtr
Это на x64. На x86 он всегда 4.
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38835061
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныЭто на x64. На x86 он всегда 4.
Any CPU не позволяет сделать вывод о размере указателя.Никакого противоречия
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38835063
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилтолько не можешь предсказать 4 или 8 байт будет IntPtrСон Веры ПавловныЭто на x64. Похоже на то.
Даже и не предскажешь путем проверки типа OS на IsWin64.

Ну, значит надо аккуратно типы писать, чтоб было универсально.
В этом топике я вроде справился.
Ну опять же, справился или "подтасовал"? Понятно, что если я использую 3 элемента структуры из 10-ти и эти 3 попадают "на свои места", то код будет работать, а при обращении к оставшимся 7-ми не факт.

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

Счас пытаюсь с вот этим:
17003714
но суко пока на .Net2 даже CDDS_PREPAINT/CDDS_ITEMPREPAINT нормально не отдает, а
lvcd.clrText еще глубже запрятан.

Просто если "универсальность" нереальна, то тяжело с API будет -гораздо сложнее чем в 32-битном VB6 с его Long-ами.
Пусть даже потребность в этих API 10% от оригинала.
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38835094
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилAny CPU не позволяет сделать вывод о размере указателя.Никакого противоречия
Под x86/x64 подразумевался не platform target проекта, а платформа, на которой проект запускается.
...
Рейтинг: 0 / 0
Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
    #38835113
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну опять же, справился или "подтасовал"? Понятно, что если я использую 3 элемента структуры из 10-ти и эти 3 попадают "на свои места", то код будет работать, а при обращении к оставшимся 7-ми не факт.

Теоретически, если такая неоднозначность с длинной одного и того же типа, то стало быть использование "правильных" типов должно гарантировать "универсальность" кода.
аккуратно расписывать нужно, иногда имеет смысл явно смещения задавать
на худой конец в тяжёлых случаях - в рантайме ветвиться.

а грубо проверить можно сравнив sizeof с C реализацией
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получаю список модемов через API Net4.5-работает, конвертирую в Net2 -не работает
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]