Страница 2 из 2

СообщениеДобавлено: 16.01.2016 (Сб) 11:47
Qwertiy
Adam Smith писал(а):objHTTP.GetResponseHeader("Content-Length")  в Long 'или в Decimal

Точно не в Long. Бывают файлы больше 4 ГБ.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 16.01.2016 (Сб) 13:18
Adam Smith
Бывают, но как представлю себе скачивание такого с Интернета, то сразу пропадает смысл периодичной синхронизации по расписанию.
Или таймер синхронизации должен будет сначала ждать окончания всех скачиваний. Всё таки я наверное введу какие-то ограничения.
Например ограничу
кол-во выбранных для синхронизации: 3000 файлов
размер каждого выбранного файла не более: 1,5Гб

И ещё, для проверки ссылок я думаю создавать инстансы WScript'а например, памяти это всё съест ещё больше,
но проблема с зависаниями решится за счет IWinHttpRequestEvents::OnResponseFinished. Или опять не туда копаю?

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 16.01.2016 (Сб) 20:08
Adam Smith
Как всегда, чем меньше знаешь, тем кажется проще написать такую программу. Чем больше читаю, пробую и ошибаюсь, тем запутаннее становится картина.
Избавился от нагромождения, распараллеливания и асинхрона, сделал синхронный последовательный перебор ссылок и всё уже заработало в 2 раза быстрее.
Запускать 2, 3 или 4 таких процесса с разными наборами ссылок, с каждым процессом расшаривать память отдельно и синхронизировать не надо, вроде всё.

Забыл, использую один и тот же инстанс класса, убрал objHTTP.setRequestHeader "Connection", "Close" и похоже все запросы в одном соединение исполняются.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 16.01.2016 (Сб) 20:17
Хакер
Ну и зачем тебе BSTR конвертировать в байтовый массив, чтобы потом из него вычленить какие-то данные и превратить вообще Long?

Adam Smith писал(а):Cреди API-функций есть такая, которая вернет мне данные конкретных Response Headers как это делает обертка?

Почему бы тебе не почитать документацию?
WinHttpQueryHeaders писал(а):By default WinHttpQueryHeaders returns a string. However, you can request data in the form of a SYSTEMTIME structure or DWORD by including the appropriate modifier flag in dwInfoLevel. The following table shows the possible data types that WinHttpQueryHeaders can return along with the modifier flag that you use to select that data type.
Data type Modifier flag
LPCWSTR Default. No modifier flag required.
SYSTEMTIME WINHTTP_QUERY_FLAG_SYSTEMTIME
DWORD WINHTTP_QUERY_FLAG_NUMBER



Кроме того, Long запросто может не вместить размер.
Decimal не существует как самостоятельный тип, это подтип Variant-а.
Byte-а не хватит, чтобы описать все возможные Content-Type (с учётом того, что сервер может придумать свои собственные уникальные).
Date не подходит для того, чтобы хранить содержимое заголовка Last-Modified.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 16.01.2016 (Сб) 20:52
Adam Smith
Работает без зависаний там, где раньше вис рандомно. Ты прав, но ведь по сути там именно дата и время, верно?
Код: Выделить всё
Private objHTTP As Object

Private Sub Class_Initialize()

  Const WinHttpRequestOption_EnableHttpsToHttpRedirects = 12

  Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
  'Enable redirection from HTTPS to HTTP (is Off by default)
  objHTTP.Option(WinHttpRequestOption_EnableHttpsToHttpRedirects) = True
End Sub

Private Sub Class_Terminate()
  Set objHTTP = Nothing
End Sub

Public Function Status(Index As Long) As Long
On Error Resume Next
  objHTTP.Open "HEAD", RecLinks(Index).fLink, False

If Err.Number <> 0 Then Status = 400: Exit Function
'  objHTTP.setRequestHeader "Connection", "Close"
  objHTTP.send
  objHTTP.WaitForResponse
'  If objHTTP.WaitForResponse(0) Then
    Status = objHTTP.Status
    If Status = 200& Then

      Dim tmpStr As String

        tmpStr = Mid$(objHTTP.GetResponseHeader("Last-Modified"), 6&, 20&)
        Select Case Mid$(tmpStr, 4&, 3&)
          Case "Jan"
             Mid(tmpStr, 3&, 4&) = ".01."
          Case "Feb"
             Mid(tmpStr, 3&, 4&) = ".02."
          Case "Mar"
             Mid(tmpStr, 3&, 4&) = ".03."
          Case "Apr"
             Mid(tmpStr, 3&, 4&) = ".04."
          Case "May"
             Mid(tmpStr, 3&, 4&) = ".05."
          Case "Jun"
             Mid(tmpStr, 3&, 4&) = ".06."
          Case "Jul"
             Mid(tmpStr, 3&, 4&) = ".07."
          Case "Aug"
             Mid(tmpStr, 3&, 4&) = ".08."
          Case "Sep"
             Mid(tmpStr, 3&, 4&) = ".09."
          Case "Oct"
             Mid(tmpStr, 3&, 4&) = ".10."
          Case "Nov"
             Mid(tmpStr, 3&, 4&) = ".11."
          Case "Dec"
             Mid(tmpStr, 3&, 4&) = ".12."
        End Select
        tmpStr = Left$(tmpStr, 6&) & Right$(tmpStr, 13&)
        RecLinks(Index).fTime = CDate(tmpStr)
        RecLinks(Index).fType = StrConv(objHTTP.GetResponseHeader("Content-Type"), vbFromUnicode)
        RecLinks(Index).fLen = objHTTP.GetResponseHeader("Content-Length")
End Function
Про long я уже сказал, что думаю. Ты правда считаешь, стоит использовать другой тип? Какой?
Byte, я имел ввиду байтмассив, а не один байт конечно. Тыже сам пишешь, что я строку в байтмассив конвертирую. Зачем? Чтобы память в куче съэкономить.

Документацию я уже до дыр зачитал, не понимаю я её, хочешь помочь объясни или покажи правильный вариант.

UPD
Весь код класса забил, чтобы опять не подорваться из-за отсутствующей декларации.

Тестировал последний вариант по своему шортлисту серверов, ни одного зависания, тормоза только из-за хренового вайфая, 1 процесс 21261 ссылка за 2 часа.
Результаты передаются в виде строк, поэтому преобразования вынесу за пределы процесса проверки. Во фронтэнде буду конвертировать и хранить в удобном виде.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 16:07
Adam Smith
У меня есть массив элементов пользовательского типа. Насколько я понял, структура не важна, его можно копировать из памяти в обычный байт-массив. И наоборот, любую структуру SAFEARRAY можно воссоздать из байт-массива.
1 не нужно посылать в гугл, я ищу ответы тут. 2 я читал статьи на этом сайте. Но, т.к. знание у меня поверхностное, отрывочное (и другие страшные слова) я прошу рабочий пример этих 2х операций у хорошо понимающих эту тему.
Если копировать массив можно только если он одномерный и стандартного типа элементов, мне это тоже подойдёт.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 16:46
Хакер
Adam Smith писал(а):Насколько я понял, структура не важна, его можно копировать из памяти в обычный байт-массив. И наоборот, любую структуру SAFEARRAY можно воссоздать из байт-массива.


А вот и нет. При условии, что исходный массив останется на всём протяжении времени существования копии неизменным, это, конечно, можно. Но какой тогда смысл иметь в памяти два одинаковых байт-к-байту массива? Абсолютно никакого, только перерасход памяти.

При условии, что первый исходный массив перестанет существовать или подвергнется изменениям, а из второго потом будет предпринята попытка получить первый, тупое побайтовое копирование можно применять только в том случае, если пользовательский тип (UDT) первого массива не содержит:
  • Строк.
  • Variant-полей.
  • Объектных ссылок (As Object, As IUnknown, As Form328, As что угодно, если даёт ссылку на интерфейс объекта).
  • Массивов фиксированного размера (любой размерности), у которых тип элемента — что-либо из вышеперечисленного.
  • Динамических массива с любым типом элемента.
    \

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 17:09
Adam Smith
Смысл в том, что байт-массив я смогу передать одной итерацией через разшаренную память в другой процесс.
Ладно, я могу отказаться от пользовательского типа, разобью его на несколько массивов стандартных типов.
Но и такие стандартные массивы тоже нельзя копировать/восстановить из байт-массива?

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 17:22
Хакер
Дурь. Без всякого копирования массив можно сразу размещать на расшаренной памяти и работать с ним из обоих процессов.

Но опять таки, в этом случае массив не может содержать указатели, поэтому все вышеперечисленные типы либо под запретом, либо все данные, достижимые через эти указатели (прямо или косвенно), должны тоже располагаться в расшаренной памяти, за исключением, пожалуй, данных, расположенных в образах PE-модулей, таких, которые в обоих процессах загружены по одинаковым базовым адресам.

То есть, для тебя это оборачивает так: либо массив содержит «запретные» данные, и тогда даже копировать нельзя, либо не содержит, и его сразу можно размещать на расшаренной памяти. Копирование как подход осталось в аутсайдерах.

Но вообще, это, конечно, полная дурь. С таким уровнем знания понимания и осознания вещей, как может в голову придти в качестве IPC-средства использовать расшаренную память? Используй COM для IPC.

Ладно, я могу отказаться от пользовательского типа, разобью его на несколько массивов стандартных типов.
Но и такие стандартные массивы тоже нельзя копировать/восстановить из байт-массива?

Если UDT содержал элементы перечисленных запрещённых типов, то и обычные массивы с элементами этих типов под запретом. А если не содержал, то смысла массив UDT превращать в несколько параллельных массивов элементарных типов — ноль.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 18:04
Adam Smith
Использовать COM с многопоточностью? Говорено переговорено и в т.ч. тобой лично озвучено, что это не работает. А избегать тормозов мне по-любому нужно.
Допустим получил байт-массив как результат от апи функции, его по-любому придется копировать в расшаренную память. А ты пишешь, копирование ни ни.

В 2х одинаковых процессах запущенных из одного стандартного экзешника объявлены одинаковые строковые массивы (и Long массивы). Их нельзя скопировать?

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 18:05
Хакер
Adam Smith писал(а):Говорено переговорено и в т.ч. тобой лично озвучено, что это не работает.

Я не виноват, что мои слова неправильно воспринимают.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 21:39
Adam Smith
На минуту допусти, что только ты один знаешь как заставить VB6 работать с многопоточностью не падая. Представил?
Прикинь, это реальность. А иначе это давно стало бы сенсацией и разлетелось на все форумы с разделами о шестерке.

К разговору о многопоточности конечно можно вернуться ради шутки, ну понятно, что это будет бесполезный разговор.
Про ActiveX я тут уже спрашивал, где взять правильные данные для манифестов SbS. Бесполезно спрашивать, искать.
Нашел упоминание по-моему OLEView, так в ней столько хрени всякой, хорошо догадался драгдропом dll перетащить.
В меню нихрена не понятно, для человека незнакомого с OLE COM ActiveX толку от этой утилиты ноль без палочки.
Из перевода понял, что примеры дебильные и внушают людям, что многие параметры манифеста необязательны.
И даже если обойду регистрацию манифестами, снова, толку от ActiveX если граблиVB6 c многопоточностью останутся.
Задумал было написать нативную DLL, но без событий толку от неё немного, да и аддинов тех ваших уже не найдешь.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 18.01.2016 (Пн) 22:39
Хакер
А какая связь между тремя упомянутыми тобою вещами?
1. Моим предложением для IPC при многопроцессном подходе использовать COM RPC.
2. Идей применить многопоточность и предположения, что кроме меня, якобы, никто ничего не умеет.
3. SxS.

Я что-то вообще не улавливаю.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 19.01.2016 (Вт) 0:36
Adam Smith
Сначала подумал, что ты опять про Standart EXE и ActiveX DLL. Без костылей и проблем с правами только вариант сайд бай сайд манифестов.

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

Нашел только Guide COM Clients and Servers Inter-Object Communication https://www.google.ru/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwj91Iz8lLTKAhXiqnIKHXz3BMkQFggbMAA&url=https%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fwindows%2Fdesktop%2Fms691207(v%3Dvs.85).aspx&usg=AFQjCNH0F3iwvQ0zczcoiKtQonF7dS02CA&bvm=bv.112064104,d.bGQ&cad=rja

То, что я знаю о COM - это например Standart EXE и ActiveX DLL. Это межпроцессное взаимодействие?

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 19.01.2016 (Вт) 11:08
The trick
Тему особо не читал, но скажу немного о многопоточности. Ты можешь создать объекты в отдельных потоках и используя маршалинг, получать события от них в главном, без копирования памяти. Пример здесь. Там идет загрузка файла из сети в отдельном потоке с уведомлением в главный поток через события. Используя этот модуль можно работать без ограничений. Вообще почитай это, этои это.
Можешь использовать PostMessage для асинхронных уведомлений в главный поток, а расшаривание данных делать в большом многомерном массиве. И уведомлять основной поток по частям, как часть массива отработана (к примеру повесить событие или флаг), то она опять может быть использована для заполнения порожденным потоком.
Вотпример - загрузка изображений и создание из них превью в отдельном потоке с уведомлением в главный, Здесь используеться общий объект IStream для расшаривания данных. Никаких дополнительных DLL не требуется. Там же (сама тема) есть вспомогательная DLL для создания объектов из ActiveX DLL в других потоках (не моя).

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 12:29
Adam Smith
Пример в архиве TrickMTDownloader.rar в первой теме http://bbs.vbstreets.ru/viewtopic.php?f=99&t=46807 у меня в XP SP3 не работает, даже с регистрацией dll.
Манифест есть только в exe, в dll не вижу, без регистрации это работает в гостевой учетке Win7 и не работает даже с регистрацией в WinXP. Видимо дело в манифесте.

Третья тема для меня полная жесть, очень познавательно, но к моей задачке не применимо.

Вторую про NativeDLL я читал и раньше. Кажется можно в рантайме из собственного Custom ресурса выгрузить dll'ку куда-нибудь в Temp и использовать оттуда. Верно?
У меня не получалось скомпилировать нативную библиотеку, не знаю может дело в версии msvbvm, VB6 у меня установлен в Win7 и я пока не пробовал сделать это под XP.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 15:52
The trick
Adam Smith писал(а):Пример в архиве TrickMTDownloader.rar в первой теме http://bbs.vbstreets.ru/viewtopic.php?f=99&t=46807 у меня в XP SP3 не работает, даже с регистрацией dll.
Манифест есть только в exe, в dll не вижу, без регистрации это работает в гостевой учетке Win7 и не работает даже с регистрацией в WinXP. Видимо дело в манифесте.

Да, дело было в манифесте, исправил, перезалил. Сейчас работает на XP тоже.
Adam Smith писал(а):Третья тема для меня полная жесть, очень познавательно, но к моей задачке не применимо.

Тебе нужна первая и четвертая.
Adam Smith писал(а):Вторую про NativeDLL я читал и раньше. Кажется можно в рантайме из собственного Custom ресурса выгрузить dll'ку куда-нибудь в Temp и использовать оттуда. Верно?
У меня не получалось скомпилировать нативную библиотеку, не знаю может дело в версии msvbvm, VB6 у меня установлен в Win7 и я пока не пробовал сделать это под XP.

Так не нужно делать. Не знаю как ты делал, но если следовать инструкции то все должно работать.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 17:56
Adam Smith
The trick писал(а):Так не нужно делать.

Логичнее сделать утилиту одним файлом. Почему не нужно? Антивирусы к таким вещам не равнодушны или другие причины?

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 19:31
The trick
Adam Smith писал(а):
The trick писал(а):Так не нужно делать.

Логичнее сделать утилиту одним файлом. Почему не нужно? Антивирусы к таким вещам не равнодушны или другие причины?

Я думаю можно сделать один единственный EXE, вместо ActiveX DLL использовать приватный VB-шный класс, просто нужно сделать tlb с описанием интерфейса этого класса для маршаллинга и вставить ее в ресурсы EXE (соответственно через манифест зарегить). Ну это все чтобы получать события. Но лучше не заморачиваться а сделать как я скинул выше пример с получением thumnail'ов. Там никаких зависимостей, но уведомлять придется через PostMessage.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 22:15
Adam Smith
Докачал olelib.tlb, clsTrickSubclass2.cls и EXEInitialize.tlb уже были раньше. clsTrickSubclass2.cls я так понял для безопасного сабклассинга в IDE.
Там грязные трюки c асмом, я попробую избавится от него. Или не стоит этого делать? За конкретный пример, прямые руки и советы СПАСИБО!
Теперь медитируя на код буду выпрямлять свои.

UPD
Так там оказывается дохрена чего на ассемблере.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 20.01.2016 (Ср) 22:52
The trick
Adam Smith писал(а):Так там оказывается дохрена чего на ассемблере.

EXEInitialize и modMultiThreading нельзя изменить так, чтобы не использовался ассемблер, если смущает использование динамического кода, можешь использовать инлайн ассемблер (это будет вшивать ассемблерный код непосредственно в EXE).
Модуль сабклассинга можешь в принципе заменить на обычный сабклассинг, просто мой класс очень удобный и безопасный в отладке поэтому я его использую.
Вот еще пример использования, а вот с использованием ActiveX DLL.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 21.01.2016 (Чт) 12:09
Adam Smith
Нет, меня устраивает любой безпроблеммный вариант. Проверил на virustotal.com только одно ложное срабатывание. Значит у антивиров проблем с этим нет. Теперь тестирую работоспособность на разных осях в виртуалках.
Win2K SP4
Изображение
Но это и не критично, я планировал поддержку от XP до Win10, а с ними пока проблем нет.

Re: Следую совету, заодно узнаю на сколько это полезно

СообщениеДобавлено: 23.01.2016 (Сб) 0:00
Adam Smith
Господа, я правильно понял, ADO 2.5 ещё в Win2K позволяла обращаться к URL например за получением списка папок и файлов?
ADO 2.5 писал(а): Record object
ADO 2.5 introduces the Record object to represent and manage a row from a Recordset or a data provider, or an object encapsulating a semi-structured data, such as a file or directory.
Stream object
ADO 2.5 also introduces the Stream object to represent a stream of binary or text data.
URL binding
ADO 2.5 introduces the use of a URL, as an alternative to a connection string and command text, to name data store objects. A URL can be used with the existing Connection and Recordset objects, as well as with the new Record and Stream objects.
Data providers supporting URL binding
ADO 2.5 supports OLE DB providers that recognize the URL schemes. This includes OLE DB Provider for Internet Publishing, which accesses the Windows 2000 file system and recognizes the existing HTTP scheme.

Никто не предложил это направление. Может потому, что я задавал не те вопросы?

Понял. Я планирую обращаться к Web-серверам не только MSIIS.
Microsoft OLE DB Provider for Internet Publishing писал(а):Используется для доступа к Web-серверам и ресурсам, обслуживаемым Microsoft FrontPage или Microsoft Internet Information Server