I'd liked to know whether it is possible to call a function in VBScript from C#. Let me try to clarify. I'm using an application (Quick Test Professional or "QTP") that automates another application, mostly using VBScript. There is the ability, via an add in model, to extend the test functionality by writing add-ins to the testing application (QTP) that are .NET assemblies. The basic workflow is that the VBScript tests automate the test application, and can call methods on a class in the extensibility add in assembly to do more complicated things. This part works fine.
What I'd like to know is whether it is possible for my C# code (in the extensibility add in assembly) to call back to a function in the VBScript. I don't think the test application framework (QTP) explicitly supports this, so I'm wondering if there is any way to do this using standard interop techniques. I was half way thinking of using GetRef() to get a reference to the VBScript function of interest, passing this as a parameter to a method I call in the extensibility addin (I suspect I would run into marshaling issues even at this point?) and then within the C# code of my extensibility add in, somehow call a method on this object; this is where I'm completely lost (since I don't know how to do this without the necessary type information normally used in reflection).
I'm thinking this may not be possible, but would like confirmation if that's the case.
Thank you!
In the end not so hard but finding it out was harder
In vbscript set a=getref
In c# declare the ref as an object
https://community.saas.hpe.com/t5/Unified-Functional-Testing/C-compile-on-the-fly-thru-dotnetfactory/m-p/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;
}
And then in vbs
Set oCallMe = GetRef("CallMeBackWithAParameter")
oTestCom.InitUFTCallBack(oCallMe)
oTestCom.callMeBack2()
Function callMeBackWithAParameter(P1)
print "I wass called back from C# having value " & P1
End Function
How does the VBScript call the C# code? I suspect that it is really calling on QTP, and QTP is calling the C# code. In that case, only QTP could possibly call the VBScript back.
Under what circumstances would your C# code call back? I doubt that VBScript can be called back asynchronously.
That's a toughie.
You MAY want to try writing an event handler in the VBScript side for the .NET component and raising an event on the .NET side when you want the function to be called.
Just be warned it may not even work, as it really depends on QTP's scripting engine. And even if it should, don't be surprised if it becomes an exercise in frustration.
See examples on WSH and event handling http://msdn.microsoft.com/en-us/library/ms974564.aspx Again, this probably won't apply to QTP, but it's to give you an idea of potential approach to the problem.
Edit: Additional link which may or may not help!
http://www.west-wind.com/presentations/dotnetfromVfp/DotNetFromVfp_EventHandling.asp
Related
I was wondering how I could program like a certain API, I have written an algorithm that I want to publish so people can use it, but I don't want people to see the code, and steal it? Paranoid, I know, but still.
How is that made, so for instance I can in a C# script (the API would also be written in C#), include it (with using ApiName) and use the functions inside, for instance if the API has a function that I program like "void Calculate(float x, float y)", and then from a script they can call "Calculate(100, 200)" for instance. I know it's somehow possible because of the Windows API, etc. Also is creating a Class Library the same thing?
Before any code runs, it is either compiled or interpreted into binary. This is highly simplified but that is the general idea. As long as a library or API provides an interface like names of functions, the implementation itself can be compiled and still work.
For C#, NuGet is a good example, you can create a NuGet of your code (see https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package) where the public function and method signatures will be visible and usable but the implementations will be compiled. DLLs work in a similar way. You can reference them and call their public members but not see the code unless you use a tool to decompile them.
While creating a plugin for a third party application I hit a problem that the type library provided by the creators of the application does not contain all methods available for the plugins.
Basically everything works if I use VisualBasic and don't have the Option Strict On set. As soon as I set it to "On" I get errors that Late binding is not available with Strict On.
Now I really would like to port this code to C#, but I can't figure out how to get those methods to work.
The plugin system works in the way that my plugin gets an Application object and later I just call:
Application.IntermediateObject.InterestingMethod(Variable) - this works fine in VB without "Strict On"
In C# this doesn't even compile as IntermediateObject does not contain a definition of "InterestingMethod" (as I can also see by using the Windows SDK COM Object Browser).
My best guess so far was that I should be able to get to it with something like that:
IntermediateObject.GetType().GetMethod("InterestingMethod");
But the result of that is just "null".
Am I doing something wrong here? or is this a dead-end and I must stick to VB?
PS: I have no power to make the application creators fix their type library, so that is not an option.
You could try to employ the dynamic keyword here:
dynamic tmp = Application.IntermediateObject;
tmp.InterestingMethod(variable);
This might work, although I am not certain as reflection doesn't seem to work.
I've been searching for this for quite a while with no luck so far. Is there an equivalent to Java's ClassFileTransformer in .NET? Basically, I want to create a class CustomClassFileTransformer (which in Java would implement the interface ClassFileTransformer) that gets called whenever a class is loaded, and is allowed to tweak it and replace it with the tweaked version.
I know there are frameworks that do similar things, but I was looking for something more straightforward, like implementing my own ClassFileTransformer. Is it possible?
EDIT #1. More details about why I need this:
Basically, I have a C# application and I need to monitor the instructions it wants to run in order to detect read or write operations to fields (operations Ldfld and Stfld) and insert some instructions before the read/write takes place.
I know how to do this (except for the part where I need to be invoked to replace the class): for every method whose code I want to monitor, I must:
Get the method's MethodBody using MethodBase.GetMethodBody()
Transform it to byte array with MethodBody.GetILAsByteArray(). The byte[] it returns contains the bytecode.
Analyse the bytecode as explained here, possibly inserting new instructions or deleting/modifying existing ones by changing the contents of the array.
Create a new method and use the new bytecode to create its body, with MethodBuilder.CreateMethodBody(byte[] il, int count), where il is the array with the bytecode.
I put all these tweaked methods in a new class and use the new class to replace the one that was originally going to be loaded.
An alternative to replacing classes would be somehow getting notified whenever a method is invoked. Then I'd replace the call to that method with a call to my own tweaked method, which I would tweak only the first time is invoked and then I'd put it in a dictionary for future uses, to reduce overhead (for future calls I'll just look up the method and invoke it; I won't need to analyse the bytecode again). I'm currently investigating ways to do this and LinFu looks pretty interesting, but if there was something like a ClassFileTransformer it would be much simpler: I just rewrite the class, replace it, and let the code run without monitoring anything.
An additional note: the classes may be sealed. I want to be able to replace any kind of class, I cannot impose restrictions on their attributes.
EDIT #2. Why I need to do this at runtime.
I need to monitor everything that is going on so that I can detect every access to data. This applies to the code of library classes as well. However, I cannot know in advance which classes are going to be used, and even if I knew every possible class that may get loaded it would be a huge performance hit to tweak all of them instead of waiting to see whether they actually get invoked or not.
POSSIBLE (BUT PRETTY HARDCORE) SOLUTION. In case anyone is interested (and I see the question has been faved, so I guess someone is), this is what I'm looking at right now. Basically I'd have to implement the profiling API and I'll register for the events that I'm interested in, in my case whenever a JIT compilation starts. An extract of the blogpost:
In your ICorProfilerCallback2::ModuleLoadFinished callback, you call ICorProfilerInfo2::GetModuleMetadata to get a pointer to a metadata interface on that module.
QI for the metadata interface you want. Search MSDN for "IMetaDataImport", and grope through the table of contents to find topics on the metadata interfaces.
Once you're in metadata-land, you have access to all the types in the module, including their fields and function prototypes. You may need to parse metadata signatures and this signature parser may be of use to you.
In your ICorProfilerCallback2::JITCompilationStarted callback, you may use ICorProfilerInfo2::GetILFunctionBody to inspect the original IL, and ICorProfilerInfo2::GetILFunctionBodyAllocator and then ICorProfilerInfo2::SetILFunctionBody to replace that IL with your own.
The great news: I get notified when a JIT compilation starts and I can replace the bytecode right there, without having to worry about replacing the class, etc. The not-so-great news: you cannot invoke managed code from the API's callback methods, which makes sense but means I'm on my own parsing the IL code, etc, as opposed to be able to use Cecil, which would've been a breeze.
I don't think there's a simpler way to do this without using AOP frameworks (such as PostSharp). If anyone has any other idea please let me know. I'm not marking the question as answered yet.
I don't know of a direct equivalent in .NET for this.
However, there are some ways to implement similar functionality, such as using Reflection.Emit to generate assemblies and types on demand, uing RealProxy to create proxy objects for interfaces and MarshalByRefObject objects. However, to advise what to use, it would be important to know more about the actual use case.
After quite some research I'm answering my own question: there isn't an equivalent to the ClassFileTransformer in .NET, or any straightforward way to replace classes.
It's possible to gain control over the class-loading process by hosting the CLR, but this is pretty low-level, you have to be careful with it, and it's not possible in every scenario. For example if you're running on a server you may not have the rights to host the CLR. Also if you're running an ASP.NET application you cannot do this because ASP.NET already provides a CLR host.
It's a pity .NET doesn't support this; it would be so easy for them to do this, they just have to notify you before a class is loaded and give you the chance to modify the class before passing it on the CLR to load it.
That's what I wanna achieve :
There will be dll which contains only methods which calls my actual methods from my application and I can share that dll with outside world regardless of which methods it includes because actual methods will be in the dll in my application but if some one uses that outside dll he/she can manages to get my application to do something in limits of I desire.
I hope I could describe what I want. I don't know if you have ever used Skype4COM.dll. It actually works like that, it somehow connects to Skype Client and let me call some one I want. For example :
Skype s = new Skype();
s.PlaceCall("phoneNumber");
I import Skype4COM dll in my project and when i write code like above in C#, it connects to Skype and make a call.
I think there is no actual methods which makes calls in Skype4Com.dll. I think it only does have some sort of methods which reach actual methods in Skype API and make the call so whatever the developers change in Skype, it doesn't affect Skype4Com.dll wrapper as long as signature stays the same.
So, that's what I want to achive, I am not quite interested in writing wrappers tho, that was a sample case, I want to write a dll which reachs my API and uses method signatures and let people use the application from outside so as long as the signatures stay same, if I want to change something between block I don't need to change the dll given out to outside..
Thank in advance....
If I understand you correctly, you want to expose a limited subset of the functions of your application to outside users. In effect, you want to offer a service, but nothing else.
Then you should use Windows Communication Foundation to host a service inside of your application (or elsewhere). This service could use industry-standard protocols like SOAP; or could use REST; or it could use faster binary transfers over TCP/IP for your .NET clients.
It's perfect for a service-oriented situation like yours.
What you're describing is a COM wrapper around Skype. If you really want a COM wrapper around your C# DLL, you can do that. Microsoft has provided an example that demonstrates how to create a COM Class from C#.
If you're looking into providing a wrapper around your code from managed DLLs, then it's as simple as providing a public interface that consumers of your DLL can use. You'll probably also want to install your code in the GAC (Global Assembly Cache) so that anyone that wants to call into your API can do so without putting copies of your code all over their system.
You could make everything internal instead of public inside this DLL. Internal keyword restricts access to classes, methods or properties to assembly while public keyword allows access from other assemblies
I'd like to execute JavaScript code from within a C# assembly and have the results of the JavaScript code returned to the calling C# code.
It's easier to define things that I'm not trying to do:
I'm not trying to call a JavaScript function on a web page from my code behind.
I'm not trying to load a WebBrowser control.
I don't want to have the JavaScript perform an AJAX call to a server.
What I want to do is write unit tests in JavaScript and have then unit tests output JSON, even plain text would be fine. Then I want to have a generic C# class/executible that can load the file containing the JS, run the JS unit tests, scrap/load the results, and return a pass/fail with details during a post-build task.
I think it's possible using the old ActiveX ScriptControl, but it seems like there ought to be a .NET way to do this without using SilverLight, the DLR, or anything else that hasn't shipped yet. Anyone have any ideas?
update: From Brad Abrams blog
namespace Microsoft.JScript.Vsa
{
[Obsolete("There is no replacement for this feature. " +
"Please see the ICodeCompiler documentation for additional help. " +
"http://go.microsoft.com/fwlink/?linkid=14202")]
Clarification:
We have unit tests for our JavaScript functions that are written in JavaScript using the JSUnit framework. Right now during our build process, we have to manually load a web page and click a button to ensure that all of the JavaScript unit tests pass. I'd like to be able to execute the tests during the post-build process when our automated C# unit tests are run and report the success/failure alongside of out C# unit tests and use them as an indicator as to whether or not the build is broken.
The code should be pretty self explanitory, so I'll just post that.
<add assembly="Microsoft.Vsa, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies>
using Microsoft.JScript;
public class MyClass {
public static Microsoft.JScript.Vsa.VsaEngine Engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
public static object EvaluateScript(string script)
{
object Result = null;
try
{
Result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine);
}
catch (Exception ex)
{
return ex.Message;
}
return Result;
}
public void MyMethod() {
string myscript = ...;
object myresult = EvaluateScript(myscript);
}
}
You can use the Microsoft Javascript engine for evaluating JavaScript code from C#
Update: This is obsolete as of VS 2008
You can run your JSUnit from inside Nant using the JSUnit server, it's written in java and there is not a Nant task but you can run it from the command prompt, the results are logged as XML and you can them integrate them with your build report process.
This won't be part of your Nunit result but an extra report.
We fail the build if any of those test fails.
We are doing exactly that using CC.Net.
I don't know of any .NET specific way of doing this right now... Well, there's still JScript.NET, but that probably won't be compatible with whatever JS you need to execute :)
Obviously the future would be the .NET JScript implementation for the DLR which is coming... someday (hopefully).
So that probably leaves running the old ActiveX JScript engine, which is certainly possible to do so from .NET (I've done it in the past, though it's a bit on the ugly side!).
If you're not executing the code in the context of a browser, why do the tests need to be written in Javascript? It's hard to understand the bigger picture of what you're trying to accomplish here.
Could it be simpler to use JSUnit to write your tests, and then use a WatiN
test wrapper to run them through C#, passing or failing based on the JSUnit results?
It is indeed an extra step though.
I believe I read somewhere that an upcoming version of either MBUnit or WatiN will have the functionality built in to process JSUnit test fixtures. If only I could remember where I read that...