powered by simpleCommunicator - 2.0.48     © 2025 Programmizd 02
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / PBNI Wizard
25 сообщений из 43, страница 1 из 2
PBNI Wizard
    #39495818
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть PBNIWizard (в комплекте PB10.5), но как понимаю старый, т.к. инстал при старте выдает ошибку:
---------------------------
Windows Script Host
---------------------------
Сценарий: C:\Program Files (x86)\Sybase\PowerBuilder 10.5\SDK\PBNI\Wizards\VCWizards\PBNIWizard8\install.wsf
Строка: 7
Символ: 8
Ошибка: Неверная ссылка на корень в разделе реестра "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VC\ProductDir".
Код: 80070002
Источник: WshShell.RegRead
-------------------------

На ПК VS2017, NET 4.6, W7 (64).

Что сделать, чтобы установить PBNIWizard и пользоваться?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39495889
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Он на директорию похоже ругается
Попробуйте поставить в корень диска C:
...
Рейтинг: 0 / 0
PBNI Wizard
    #39495911
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spas2001Он на директорию похоже ругается
Попробуйте поставить в корень диска C:
Эт я понимаю.
Возможно будет достаточно в файлах deploy.bat и install.wsf скорректировать соответствующие названия и значения переменных, по аналогии различий между одноименными файлами в каталогах PBNIWizard (7.0) и PBNIWizard8 (8.0).
В первом ссылка на:
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Setup\VC\ProductDir"
а во втором ссылка на:
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VC\ProductDir"

Но у меня VS2017 (15.0) и W7 (64) и такого раздела реестра нет.

К тому же, в обоих вариантах файлов указывается соответственно:
"C:\Program Files\Microsoft Visual Studio 7"
"C:\Program Files\Microsoft Visual Studio 8"
а у меня скорее всего надо указать:
"C:\Program Files (x86)\Microsoft Visual Studio"
а может и продолжить путь по имеющейся цепочке:
"C:\Program Files (x86)\Microsoft Visual Studio\2017"
т.к. другого не вижу.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39496225
Hennadiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AIS, возможно я не прав, но судя по всему проблема в несовместимости 32/64 битных приложений. Как вариант, смоделировать ситуатуцию на 32 виртуалке.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39496319
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сам создай ключи, в чем проблема?
Ну и поставить соота=ветственно VC 7.0 и 8.0
...
Рейтинг: 0 / 0
PBNI Wizard
    #39496343
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spas2001Сам создай ключи, в чем проблема?
Ну и поставить соота=ветственно VC 7.0 и 8.0
Проблема в том, что для VS2017 не знаю куда, что прописывать, чтобы была "правильная" связь с РВ (установка PBNI).
Задачу решил установкой VS2015. Хотя для него чуть пришлось пути допилить (таки W7 и х64 в тандеме дали свое Г), но все получилось.
ПС. Конечно жалко, что такое с VS2017 не получилось, да и хрен с ним.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39620462
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подниму тему, нужен совет или комментарий по опыту.
Сделал внешнее решение одной и той же задачи при помощи DLL с экспортированной функцией и через PBX. И то и другое работает. Возник вопрос:
Что предподчительней использовать в проекте DLL или PBX?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39620607
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AIS,

C PBNI больше возможностей. Например можно напрямую обращаться к объектам и вызывать функции ПБ из С++.
Но с ним больше мороки по поддержке при выходе новых версий ПБ.
Так что если возможностей DLL хватает то есть смысл именно этот вариант использовать, а перейти на PBNI только когда вознитнет необходимость.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39620639
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Спасибо за совет. Да, согласен, с PBX хлопот больше, но есть и не малые плюсы.
На счет проблем с выходом новых версий РВ, то это наверное решающий фактор, т.к. в последних версиях PBX уже не идет в комплекте, а ориентир на VS, если я не ошибаюсь.

А если смотреть с точки зрения защиты кода, т.е. спрятать, то DLL снова проигрывает, или без разницы?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39620763
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AISА если смотреть с точки зрения защиты кода, т.е. спрятать, то DLL снова проигрывает, или без разницы?
Без разницы. И то и то - DLL
...
Рейтинг: 0 / 0
PBNI Wizard
    #39620790
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyAISА если смотреть с точки зрения защиты кода, т.е. спрятать, то DLL снова проигрывает, или без разницы?
Без разницы. И то и то - DLL
С этим, конечно, не спорю. Но если только просто поверхностно взглянуть на экспортируемые функции DLL и PBX, то это большая разница: у DLL - все как на ладони*, а у PBX - уй поймешь* о чем они. Не правда ли?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39622492
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создаю в PBX функцию вычисления MD5 из переданного строкового аргумента:
MD5 не работает с входящим аргументом
Код: plaintext
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.
HCRYPTPROV CryptProv;
HCRYPTHASH CryptHash;
BYTE BytesHash[16];
DWORD dwHashLen = 16;
_TCHAR theOut[MAX_PATH];

/* если задаю аргумент так, работает правильно */
// char *data = "test f_md5";
/* если беру входящий аргумент "test f_md5" из функции f_md5(ref string), то не работает правильно */
////////
char *data;
LPCTSTR lptheInput = NULL;
pbstring val = ci->pArgs->GetAt(0)->GetString();
lptheInput = m_pSession->GetString(val);
data = (LPSTR)lptheInput;
///////

BYTE *pbBuffer = (BYTE*)data;
DWORD dwBufferLen = strlen(data);
if (CryptAcquireContext(&CryptProv,
	NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
	{
		if (CryptCreateHash(CryptProv, CALG_MD5, 0, 0, &CryptHash))
		{
			if (CryptHashData(CryptHash, pbBuffer, dwBufferLen, 0))
			{
				if (CryptGetHashParam(CryptHash, HP_HASHVAL, BytesHash, &dwHashLen, 0))
				{
					CHAR hexcharset[] = "0123456789abcdef";
					for (int j = 0; j < dwHashLen; j++)
					{
						theOut[j*2] = hexcharset[BytesHash[j] >> 4];
						theOut[(j*2)+1] = hexcharset[BytesHash[j] & 0x0F];
					}

				}
				else {
					//"Error CryptGetHashParam";
				}
			}
			else {
				//"Error CryptHashData";
			}
		}
		else {
			//"Error CryptCreateHash";
		}
	}
	else {
		//"Error CryptAcquireContext";
	}
	CryptDestroyHash(CryptHash);
	CryptReleaseContext(CryptProv, 0);

         ci->returnValue->SetString(theOut);

}
return pbxr;


Где ошибка или как правильно сделать?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39622605
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AIS
Код: plaintext
1.
data = (LPSTR)lptheInput;


data - указатель на строку в кодировке ANSI
lptheInput - указатель на строку в кодировке Unicode (UTF-16)

Во-первых, нельзя так принудительно менять тип, не преобразовав данные (там потом следующий strlen() неверно отрабатывает, и может еще какие-то эффекты).
Во-вторых, вам надо решить в каком формате вы будете строку передавать в MD5 (UTF-16 или UTF-8). ANSI - не всегда годится, т.к. будут потери символов не входящих в текущую кодовую страницу.
В-третьих, надо помнимать что MD5 от одной и той же строки в ANSI, UTF-16 и в UTF-8 будут разные.
Эта тема уже обсуждалась где-то здесь. Мое мнение - если MD5 потом передается в третьи приложения, то лучше UTF-8, т.к. для английского текста ANSI и UTF-8 совпадают, т.е. больше вероятность совместимости.
В любом случае предлагаю преобразование кодировки делать на стороне ПБ функцией Blob() со вторым параметром - кодировкой. А в модуль передавать blob и его длину, и уже его хешировать.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39622844
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

премного благодарен, таки да, с blob и UTF-8 все встало на свои места.
Еще буквально недавно Вы мне это же советовали в другой ситуации, видать не внял, все string примеряю...))
Спасибо за помощь.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39623682
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вопрос, на который не могу найти ответа.

Получаю в PB экземпляр класса и передаю его в PBNI:
Код: sql
1.
2.
3.
/* например */
ClassDefinition lcd 
lcd = nuo_test.ClassDefinition 


а как потом получить свойства класса на стороне PBNI? Например, lcd.LibraryName.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624013
avs63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
См. документацию по PBNI:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
cls = session-> GetClass(dwobj);
   fid = session-> GetFieldID(cls, "visible");
   if (fid == kUndefinedFieldID) 
      return;
   isTrue = session-> GetBoolField(dwobj, fid, isNull); 
   if (isTrue)
      session -> SetBoolField(dwobj, fid, false);
    else
      session -> SetBoolField(dwobj, fid, true);
    return ;
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624076
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
avs63См. документацию по PBNI:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
cls = session-> GetClass(dwobj);
   fid = session-> GetFieldID(cls, "visible");
   if (fid == kUndefinedFieldID) 
      return;
   isTrue = session-> GetBoolField(dwobj, fid, isNull); 
   if (isTrue)
      session -> SetBoolField(dwobj, fid, false);
    else
      session -> SetBoolField(dwobj, fid, true);
    return ;


Да вроде читал...
Для начала у меня не получается даже fid получить. Так как в доках выдает ошибку, а если так:
Код: plaintext
1.
2.
3.
...
fid = session-> GetFieldID(cls, (LPCTSTR) "visible");
...

то получаю UndefinedFieldID.
В чем причина?

РВ10.5
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624117
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, нашел ошибку. Все работает. Всем спасибо.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624372
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AISЕще вопрос, на который не могу найти ответа.

Получаю в PB экземпляр класса и передаю его в PBNI:
Код: sql
1.
2.
3.
/* например */
ClassDefinition lcd 
lcd = nuo_test.ClassDefinition 


а как потом получить свойства класса на стороне PBNI? Например, lcd.LibraryName.
Да, если передаю в PBNI параметром lcd, то могу получить lcd.LibraryName.
А как получить LibraryName ничего вообще не передавая на PBNI?
Вот например:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
...
LPCTSTR GroupName = (LPCTSTR) "test_app"; /* AppName */
pbgroup group = session->FindGroup(GroupName, pbgroup_application);
if (group == NULL) {
   ci->returnValue->SetString(_T("Group is NULL"));
} else {
   /* получаю класс в текущей библиотеке */
   pbclass cls = session->FindClass(group, GroupName); 
   if (cls == NULL) {
      ci->returnValue->SetString(_T("Class is NULL"));
   } else {
      LPCTSTR FieldName = (LPCTSTR)"classdefinition";
      pbfieldID fid = session->GetFieldID(cls, FieldName);
      if (session->IsFieldObject(cls, fid)) {
         /* сюда не проходит, хотя ClassDefinition должен быть PowerObject */
      } else {
         ci->returnValue->SetString(_T("NOT IsFieldObject"));
      }
   }
}


Что не так? Можно ли таким способом получить LibraryName?
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624774
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AISЧто не так?
Вот так нельзя делать:
Код: sql
1.
(LPCTSTR) "строка"


Все такие места в коде надо заменить на
Код: sql
1.
_T("строка")



И вообще, если у вас в коде есть конструкция (тип) перед выражением, то там скореее всего проблема. Лучше заменить ее на конструкцию static_cast<тип>(выражение).
Тогда компилятор сам подскажет вам когда нельзя так делать ))
...
Рейтинг: 0 / 0
PBNI Wizard
    #39624862
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

спасибо за помощь, поменял.
Теперь получилось получить, например, значение свойства "displayname" приложения.
А вот дальше не могу понять, что делать, чтобы получить свойство "classdefinition" приложения, которое является объектом, и далее получить из него значение LibraryName.
Если есть возможность, то подскажите хоть схематически, как это делается.
...
Рейтинг: 0 / 0
PBNI Wizard
    #39625200
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AIS,

Что-то типа этого. (Только добавить проверки на успешность выполнения)
Код: plaintext
1.
2.
3.
pbclass cls = session->FindClass(group, GroupName)
pbfieldID fid = session->GetFieldID(cls, _T("classdefinition"));
pbobject clsdef = session->GetObjectField(cls, fid, isNull);



Если это не сработает, то приведите ваш код - может по нему что-то будет видно.
У меня нет Винды с ПБ под рукой, поэтому больше ничем помочь не могу, кроме проверки вашего кода в форуме )).
...
Рейтинг: 0 / 0
PBNI Wizard
    #39625206
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще, classdefinition это же свойство объекта, а не класса.
Поэтому вам надо этот объект (приложение?) передать в pbni, и для него вызывать
GetFieldID и GetObjectField
...
Рейтинг: 0 / 0
PBNI Wizard
    #39625362
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
PB: событие "open" приложения
Код: sql
1.
2.
3.
string ls_rtn
ls_rtn = f_test(this) /* вызов функции PBX */
MessageBox("test", ls_rtn)


PBX: после корректировки
Код: plaintext
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.
...
pbboolean isNull;
/* передаю параметр - объект приложения */
pbobject obj = ci->pArgs->GetAt(0)->GetObject();
pbclass cls = ci->pArgs->GetAt(0)->GetClass();
if (cls == NULL) {
   ci->returnValue->SetString(_T("Class is NULL"));
}
else {
   LPCTSTR FieldName = _T("classdefinition");
   pbfieldID fid = session->GetFieldID(cls, FieldName);
   if (fidcls == kUndefinedFieldID) {
      ci->returnValue->SetString(_T("Undefined FieldID"));
   }
   else {
      /* в GetObjectField нужен таки объект, а не класс */
      pbobject objclsdef = m_pSession->GetObjectField(obj, fid, isNull);
      if (objclsdef == NULL) {
	 ci->returnValue->SetString(_T("ObjectField is NULL"));
      }
      else {
	 ci->returnValue->SetString(_T("ObjectField is NOT NULL")); /* сюда доходит */
      }
   }
}


А дальше не пойму как получить из PBX значение libraryname, который в РВ в событии "open" приложения можно получить так:
Код: sql
1.
2.
3.
ClassDefinition lcd
lcd = this.ClassDefinition
ls_Fullpath = lcd.LibraryName
...
Рейтинг: 0 / 0
PBNI Wizard
    #39625589
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AIS,
Код: plaintext
1.
2.
3.
4.
pbobject objclsdef = session->GetObjectField(obj, fid, isNull);  // это у вас уже есть
pbclass clsdefcls = objclsdef->GetClass();
pbfieldID library_fid = session->GetFieldID(clsdefcls, _T("libraryname"));
pbstring lirary_name = session->GetStringField(objclsdef, library_fid, isNull);
...
Рейтинг: 0 / 0
25 сообщений из 43, страница 1 из 2
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / PBNI Wizard
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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