Обратный вызов VBScript из C#

Я хотел бы знать, можно ли вызвать функцию в VBScript из С#. Позвольте мне попытаться уточнить. Я использую приложение (Quick Test Professional или QTP), которое автоматизирует другое приложение, в основном с использованием VBScript. Существует возможность с помощью модели надстроек расширить функциональные возможности тестирования путем написания надстроек для тестового приложения (QTP), которые представляют собой сборки .NET. Основной рабочий процесс заключается в том, что тесты VBScript автоматизируют тестовое приложение и могут вызывать методы класса в расширении, добавленном в сборку, для выполнения более сложных задач. Эта часть работает нормально.

Я хотел бы знать, возможно ли, чтобы мой код C# (в расширении, добавленном в сборку), вызывал функцию в VBScript. Я не думаю, что среда тестовых приложений (QTP) явно поддерживает это, поэтому мне интересно, есть ли способ сделать это, используя стандартные методы взаимодействия. Я наполовину думал об использовании GetRef() для получения ссылки на интересующую функцию VBScript, передав ее в качестве параметра методу, который я вызываю в надстройке расширяемости (подозреваю, что даже на этом этапе у меня возникнут проблемы с маршалингом?) а затем в коде C# моей расширяемости каким-то образом вызовите метод для этого объекта; здесь я полностью потерялся (поскольку я не знаю, как это сделать без необходимой информации о типе, обычно используемой при отражении).

Я думаю, что это может быть невозможно, но хотелось бы подтверждения, если это так.

Спасибо!


person Community    schedule 25.06.2009    source источник


Ответы (3)


В конце концов, не так сложно, но выяснить это было сложнее В vbscript установить a=getref В c# объявить ссылку как объект https://community.saas.hpe.com/t5/Unified-Functional-Testing/C-compile-on-the-fly-thru-dotnetfactory/mp/1611299#M22811

private object _UFTCallBackFunction = null;

 public int callMeBack2()
 {
 string[] retParts = {"Yep this is value 1"};
 _UFTCallBackFunction.GetType().InvokeMember("", 
  System.Reflection.BindingFlags.InvokeMethod, null, 
_UFTCallBackFunction, retParts);
 return 0;
 }

 public void InitUFTCallBack(object UFTCallBackFunction)
 {
 _UFTCallBackFunction = UFTCallBackFunction;
 }

А потом в вбс

Set oCallMe = GetRef("CallMeBackWithAParameter")
oTestCom.InitUFTCallBack(oCallMe)
oTestCom.callMeBack2()
Function callMeBackWithAParameter(P1)
 print "I wass called back from C# having value " & P1
End Function
person junkew    schedule 28.08.2017
comment
это сработало для меня, но мне пришлось установить последний аргумент InvokeMember на nullptr. - person Dmitry; 10.09.2017

Как VBScript вызывает код C#? Я подозреваю, что он действительно вызывает QTP, а QTP вызывает код C#. В этом случае только QTP может вызвать VBScript обратно.

При каких обстоятельствах ваш код C# вызовет обратный вызов? Я сомневаюсь, что VBScript можно вызывать асинхронно.

person John Saunders    schedule 25.06.2009
comment
Я не знаю, как VBScript вызывает код C#. Если бы мне пришлось угадывать, думаю, вы правы; скорее всего, он полагается на QTP, а QTP вызывает код C#. В идеале мой код C# должен вызывать метод VBScript в ответ на событие, вызванное в элементе управления, на который подписан код C#. - person ; 25.06.2009
comment
Да, это действительно не сработает, насколько я понимаю. VBScript — это язык сценариев. Он не понимает события или многопоточность, и я уверен, что он понятия не имеет, что его можно вызвать асинхронно. Подумайте: могли бы вы сделать это, используя только чистый VBScript? Есть ли у скрипта VBSCript вызов функции VBScript, которая позже вызывает оригинал? Я не вижу способа сделать это. - person John Saunders; 25.06.2009
comment
Да, VBScript понимает события по-разному, в зависимости от хост-приложения и используемого скриптового движка; hythlodayr ссылается на несколько веб-страниц ниже. (первая ссылка является наиболее подходящей). - person ; 25.06.2009

Это крутой.

Вы МОЖЕТЕ попробовать написать обработчик событий на стороне VBScript для компонента .NET и вызвать событие на стороне .NET, когда вы хотите, чтобы функция вызывалась.

Просто имейте в виду, что это может даже не работать, так как это действительно зависит от механизма сценариев QTP. И даже если так и должно быть, не удивляйтесь, если это станет упражнением в разочаровании.

См. примеры WSH и обработки событий http://msdn.microsoft.com/en-us/library/ms974564.aspx Опять же, это, вероятно, не будет применяться к QTP, но должно дать вам представление о потенциальном подходе к проблеме.

Изменить: дополнительная ссылка, которая может помочь или не помочь!

http://www.west-wind.com/presentations/dotnetfromVfp/DotNetFromVfp_EventHandling.asp

person hythlodayr    schedule 25.06.2009
comment
Это VBScript. Есть ли у него события? - person John Saunders; 25.06.2009
comment
Раньше у меня была такая же мысль, и я нашел ту же (первую) страницу, на которую вы ссылались. Однако я не думаю, что QTP использует WSH, и ни один из других подходов (в справочнике MSDN) для подписки на события в VBScript не работает в моем сценарии. Я думаю, это потому, что я не могу влиять на то, что передается в скриптовый движок (поскольку я не QTP), и, следовательно, нельзя использовать подход «автомагический» и вызов функций. - person ; 25.06.2009
comment
@ John: обработка событий существует уже довольно давно (вспомните Internet Explorer). Но его поддержка непоследовательна и во многом зависит от реализации скриптового движка. @ Нотр: Тогда извини. Поставщик может быть лучше подготовлен, чтобы дать вам ответ. - person hythlodayr; 25.06.2009
comment
Поставщик не слишком помог (в соответствующем вопросе, который я им задал), и я не нашел в их документации ничего, что предполагало бы его поддержку. Вот почему я решил опубликовать здесь, чтобы узнать, не пропустил ли я чего-нибудь с более общей точки зрения взаимодействия. - person ; 25.06.2009
comment
Я совершенно забыл Object_EventName. Тем не менее, это применимо к событиям COM. Это было бы немного беспорядочно для вызова из C# и проблемы сопровождения, учитывая, как мало людей помнят события COM. - person John Saunders; 25.06.2009
comment
Я был бы в порядке с «автоматическим» подходом Object_EventName, но даже он полагается на то, что приложение (в данном случае QTP) передает объект в обработчик сценариев и переводит обработчик сценариев в «подключенный» режим, поэтому он не будет работать для "скромного" добавления :( - person ; 26.06.2009
comment
Вернемся к исходной мысли: GetRef. Marshal.GetDelegateForFunctionPointer может быть ответом, но я понятия не имею, сработает ли это или нет (это был ваш первоначальный вопрос). - person hythlodayr; 26.06.2009
comment
Хм! Marshal.GetDelegateForFunctionPointer. Я не знал об этом методе. Это может просто сработать. Я должен попробовать. - person ; 29.06.2009
comment
Я попробовал это. К сожалению, я даже не мог вызвать свой код C#. Как только я попытался передать GetRef(funcionName) в качестве параметра, все потерпело неудачу еще до того, как я попал в мой код C# :( - person ; 30.06.2009
comment
Сомневаюсь, что вы все еще читаете это, но GetRef — забавный зверь. Поскольку вы должны использовать SET с GetRef, это означает, что GetRef возвращает какой-то COM-объект. Убедитесь, что вы используете правильный тип параметра для кода .NET. Может быть, просто начните с интерфейса IUnknown в качестве параметра, чтобы увидеть, попадете ли вы вообще в свой код C#. - person hythlodayr; 14.07.2009