Твиттер
Мой твиттер: https://twitter.com/vit_cs
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Мой твиттер: https://twitter.com/vit_cs
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Part 1. Веб-сервис (Web Service) в Visual Studio 10 называется “WCF Service Application”.
Иногда сразу же приложение не хочет работать в IIS (как случилось и у меня) с формулировкой типа “HTTP Error 404.3 - Not Found The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.” В таком случае помогает выполнение команды ServiceModelReg.exe -i. ServiceModelReg.exe находится в C:\Windows\Microsoft .NET\Framework\v4.0.30319. Там же находится aspnet_regiis.exe. Он помогает в том случае, если .Net 4 вдруг оказывается не зарегистрированным (см. картинку ниже) и по этой причине веб-сервис не запускается.
Part 2. Создание клиента для веб-сервиса на Delphi 7.
1. Сервис должен использовать привязку basicHttpBinding, а не wsHttpBinding. Регулируется это в Web.Config. Для его правки в Visual Studio 10 можно воспользоваться утилитой WCF Service Configuration Editor (можно выбрать пункт Edit WCF Configuration из контекстного меню для Web.Config).
2. Необходимо обновить утилиту импорта WSDL. Взять ее можно здесь: http://cc.embarcadero.com/item/24535. Пользоваться ею просто, например так:
WSDLImp.exe -P http://localhost:2708/Service1.svc?wsdl
В результате будет создан файл Service1.pas, который нужно подключить к проекту клиента в Delphi 7. Пользоваться очень просто:
uses Service1.pas; |
3. Delphi 7 BUG. При попытке обратиться к веб-сервису из клиента, написанного на Delphi 7, может возникать Access Violation (см. картинку ниже). Возникает эта ошибка не везде. У меня на Windows 7 ее нет, а на Windows Server 2008 - проявилась.
Фикс для этой ошибки находится в том же архиве, что и новая утилита импорта WSDL (http://cc.embarcadero.com/item/24535). НО НЕ ТОРОПИТЕСЬ заменять ваши исходники SOAP на файлы из архива. Этот “патч” что-то лечит, а что-то калечит :-) У меня при его использовании перестали передаваться в веб-сервис строковые параметры вызова (в значениях параметров всегда содержался null). Для того, чтобы справиться с ошибкой Access Violation, нам необходимы только два файла из этого патча: PrivateHeap.pas и Rio.pas. Их (только их!) нужно добавить в Delphi-проект клиента веб-сервиса.
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
HTTP-сервер в Indy 9 представлен компонентом TIdHTTPServer. Чтобы включить использование SSL (HTTPS), нужно у объекта TIdHTTPServer свойство IOHandler связать с объектом типа TIdServerIOHandlerSSL, в котором в поле CertFile прописать путь к файлу сертификата, а в KeyFile - путь к файлу с приватным ключом.
Файл сертификата имеет примерно такое содержимое:
Файл с приватным ключом выглядит примерно так:
Но что делать, если необходимо, чтобы сертификат и ключ были “вшиты” в приложение? Я использую следующую технику - после загрузки и инициализации библиотеки ssleay32.dll подменяю указатели на функции IdSslCtxUseCertificateFile и IdSslCtxUsePrivateKeyFile (они объявлены в IdSSLOpenSSLHeaders) на мои реализации этих функций, которые читают сертификат и ключ не из файлов, а из памяти.
unit uOpenSSL; |
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
В GitHub я выложил обновленную версию VHashedStringList. Сделаны следующие добавления/изменения:
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
У меня 2 аккаунта на GitHub. И несколько разных репозиториев для разных проектов - некторые должны заливаться на GitHub под первым аккаунтом, другие - под вторым. Я использую Git-клиент TortoiseGit. И столкнулся со странной проблемой - под первым аккаунтом все хорошо работает, а под вторым Push обламывается в формулировкой “error code 128 git did not exit cleanly”. Оказалось, что иногда для второго аккаунта используется ssh-key от первого. Лечится проблема удалением ключей (Remove Key) из Pagent (PuTTY authentication client).
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Для вызова внешнего приложения из программы на Delphi обычно используется функция WinAPI CreateProcess. Но как получить то, что это приложение выводит в консоль, и, например, отобразить в логе программы? Варианта два. Первый: пере-направить вывод консольного приложения в файл и потом прочитать этот файл. Однако, создавать временный файл не охота. А кроме того, такой способ не всегда хорошо работает. Есть другой способ - использовать пайпы (pipes). Ниже приведен код процедуры RunDosCommand на Delphi, который использует этот способ. Весь вывод на консоль записывается в AMemo: TMemo.
function RunDosCommand(ACmdString: String; AMemo: TMemo; |
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Для преобразования _TCHAR в QString и обратно (QString в _TCHAR) я объявил в tqchar.h пару простых макросов: _TQSTRING_TQCHAR.
Кстати, нашел хороший плагин для Visual Studio чтобы копировать код в HTML с подсветкой синтаксиса: Copy As HTML.
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Наконец-то появилась версия ASProtect 1.65 в которой заявлена совместимость с Delphi XE и XE2. Я попробовал - созданный в Delphi XE2 и запакованный новым “аспром” exe действительно запускается и работает. Ошибок пока не замечено.
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
Столкнулся с интересным багом при получении информации о версии из ресурсов (Visual Studio 10, C++).
Access Violation возникает при выполнении VerQueryValue (см. картинку).
Причем, ошибка возникает только если используется Multi-Byte Character Set. А если выставить в свойствах проекта Use Unicode Character Set, то ошибка пропадает. Из этого можно сделать вывод, что баг именно в VerQueryValueA, а в VerQueryValueW его нет.
Что ж, решение проблемы заключается в переписывании функции чтения информации о версии таким образом, чтобы всегда использовалась функция VerQueryValueW. Ниже приведен листинг готовой функции.
UPD 30.01.2014. Спустя полтора года выяснилось, что и с использованием VerQueryValueW возможен Access Violation. Что же, лучше поздно чем никогда. Дело в том, что эта функция рассчитана на то, чтобы быть использованной совместно GetFileVersionInfo. Возможно, VerQueryValue может в каких-то случаях модифицировать ресурс. В общем, фикс заключается в том, что нужно выделить участок памяти (например, с помощью LocalAlloc), скопировать в него информацию о версии из ресурса (CopyMemory), и использовать его при вызове VerQueryValue. Реализация приведена ниже.
void ReadVersion(_TCHAR * szVer, int cbVer, const _TCHAR * szEntry) |
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru
1. Скачать и установить Qt for Visual Studio 2008: http://qt.nokia.com/downloads/windows-cpp-vs2008 (каталог установки не должен содержать пробелов, например это может быть C:\qt\4.8.2)
2. Скачать и установить Visual Studio Add-in: http://qt.nokia.com/downloads/visual-studio-add-in.
Сборка Qt у меня заняла несколько часов.
2. По-умолчанию библиотеки Qt компилируются в режиме Multi-threaded DLL - /MD (для Debug - Multi-threaded Debug DLL - /MDd). Что означает наличие зависимостей от msvcr90.dll и msvcp90.dll. Т.е. при установке программы возможно потребуется устанавливать Microsoft Visual C++ 2008 Redistributable Package. Чтобы избавиться от этой зависимости нужно перед сборкой Qt поправить qmake.conf ( C:\qt\4.8.2 \mkspecs\win32-msvc2008\qmake.conf) следующим образом:
заменить строки
QMAKE_CFLAGS_RELEASE = -O2 -MD
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MDd
на
QMAKE_CFLAGS_RELEASE = -O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MTd
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru