I've compiled C# code into a DLL, but have little experience with them. My C# code contains a class HelloWorld with a static method Print(). I'd like to use this DLL in VBScript to call the method Print(). I know this is base, but I'm using this as a test for a larger scale project that will be compiled to DLL in the end. What's the declare look like for that and how would the method call look?
Important: Both methods will work only if the DLL exposes a COM interface.
If your dll is registered with the system, use CreateObject with it's ProgID.
Set myObject = CreateObject("MyReallyCoolObject.HelloWorld")
myObject.Print
If your object is not registered on the system, use GetObject with a path to the file containing your object. Make sure your object exposes the proper interface. (The second parameter is optional. Here you can provide a class name if your object exposes more than one.)
Set myObject = GetObject("C:\some\path\helloworld.dll", "appname.HelloWorld")
myObject.Print
I think you might be looking for Registration-Free COM. This SO answer regarding the Microsoft.Windows.ActCtx should help specifically for VBScript.
Keep in mind that COM doesn't support static methods, so you'll have to make your Print method into an instance method.
How to call a .NET DLL from a VBScript
Related
I have no idea what COM is, just only need to use few methods via COM.
But is there any COM browser that will show methods inside gicen interface? By name or GUID or something.
Does COM stores soem metadata like comments to interfaces etc?
Interfaces defined in a type library (.tlb file, which can be embedded in a DLL) are described in it (the OLE/COM object viewer can show them), but hardly documented in it.
Others are only defined in the Windows headers (or in a third-party library's headers). To view the actual documentation, the best is to look it up on MSDN (or just Google the interface name, which works most of the time).
Visual Studio 2008 C++ Windows Xp SP3
I have created a wxWidgets form (using wxFormBuilder) and have buttons/menus/toolbars all generating events to call various methods (all this works perfectly). Each of these event methods is defined like this:
void cLoggingFrame::me_InsertCommentText(wxCommandEvent& event);
Now, what I want to be able to do is 're-use' some of these methods by calling them directly. I don't want to generate an event to be handled, I want the method to run when I call it. For example, I want to do something like this (this doesn't work)
me_InsertCommentText(NULL);
Now, I understand that I could have each event method just call another method (without parameters) that could be called from other locations, but in other languages I've been able to bypass the parameter requirement with NULL.
Is there any way to do this with wxWidgets without the need for an additional method?
Methods passed to Event-Handlers are just ordinary c++ methods, you have to pass correct parametes
something like this will do the trick
me_InsertCommentText(wxCommandEvent());
just use the event variable that is already created by wxwidgets. The command line should be like this:
me_InsertCommentText(event);
The global VB6 error handler product referred to in the following link claims to "install a small callback hook into the VBE6 debugger":
http://www.everythingaccess.com/simplyvba/globalerrorhandler/howitworks.htm
I would like to implement this product myself because I would like more control over what it is doing. How is the above product likely to be achieving what it does?
The product you are looking at is a COM component. From the documentation that is available on the web site, it sounds like the COM component implements particular component classes. The first thing to do, if you already have the product, would be to fire up SysInternals procmon, run regsvr32 on the DLL, and figure out what component classes are implemented from the registry entries that are created. Once you know this, MSDN may be able to tell you what interfaces correspond to those component classes.
Microsoft developed a framework called Active Scripting that allows you to host a script engine and inject debugging capabilities. If one assumes that VB6 produces an exe that ties into that framework, you might be able to do:
Create a COM component that implements IApplicationDebugger
Implement IApplicationDebugger::onHandleBreakPoint to be able to respond to errors in the VB code
Read MSDN KB Q222966 to find out how to call back to VB from onHandleBreakPoint
It looks like the product injects the ErrEx class using IActiveScript::AddNamedItem. To provide the same behaviour, Implement IActiveScriptSite::GetItemInfo on the same COM component to return a pointer to an instance of (and the associated TypeInfo for) a COM component that implements the same interface as ErrEx. In your implementation of ErrEx.EnableGlobalErrorHandler you would do the following:
CoCreateInstance inproc Process Debug Manager
Cast reference to IRemoteDebugApplication
Register an instance of your IApplicationDebugger component using IRemoteDebugApplication::ConnectDebugger
I glossed over calling IActiveScript::AddNamedItem because I have no idea how you get a pointer to IActiveScript from a running process. Also, I don't know if creating a new instance of the Process Debug Manager will work, or if you somehow have to hook into an existing instance.
I apologize for the confusing explanation, missing information, and glossing over large parts of the process, but this is going waaay back...
You will want to read the Active Scripting APIs article at MSDN.
Like the title says, i want to disable images, and ActiveX Controls in the vb6 webbrowser control using DLCTL_NO_RUNACTIVEXCTLS and DLCTL_NO_DLACTIVEXCTLS
Microsoft talk about it here: http://msdn.microsoft.com/en-us/library/aa741313.aspx
But i dont see any way to access IDispatch::Invoke from the vb6 application.
Any help would be greatly appreciated.
I do not think VB6 let you to add the ambient properties. Try host the ActiveX in another container (e.g. an ActiveX host written by yourself - but I do not know how much time you want to invest to declare VB-friendly OLE interfaces and implement them - or use another ActiveX like the one at http://www.codeproject.com/KB/atl/vbmhwb.aspx instead.
You don't access IDispatch::Invoke in VB6, you just write you method and IDispatch is automagically implemented.
Public Function DlControl() As Long
DlControl = DLCTL_NO_DLACTIVEXCTLS Or ...
End FUnction
Then just open Tools->Procedure Attributes and for DlControl function open Advanced and assign Procedure ID to -5512 (DISPID_AMBIENT_DLCONTROL). That's first part.
Second part is to set the client site to you custom implementation of IOleClientSite. You'll need a custom typelib, try Edanmo's OLELIB for declaration of these interfaces.
Here is a delphi sample how to hook your implementation of IOleClientSite. Apparently you'll alse have to call OnAmbientPropertyChange at some point.
I'm developing an ActiveX EXE that exposes an specific class to a third-party software. This third-party software instanciates an object of this class and uses its methods.
Strangely, this third-party software destroys its object of my exposed class as soon as it calls an specific method, but I have no idea why this happens.
The only clue I have is that this method is the only one that returns a value. All the other ones are simple 'subs' that do not return any value, and when they are called nothing wrong happens.
I'm using VB6.
Do you guys have any idea of why it's happening?
Your object gets "destroyed" when the last reference to it is deleted. Thats normal COM behavior. Or is your object dying unexcepted and the third-party app is getting an activex error?
Some more questions:
I don't know what you mean with "data server"?
Do you have access to the source code of the third-party app?
Are you sure, the third-party app holds a reference to your object?
Is your objects Class_Terminate Method called?
EDIT:
OK, when Class_Terminate is getting called its obvious, that the third-party app has dropped its reference to your object.
As Jan stated in COM it is normal, that your object is terminated if no one is referencing it. If you would like to do some kind of caching (e.g. keep the DB connection open), you can use a global variable defined in a bas-module.
basGlobal.bas
Global AGlobalVariable As Object
Connector.cls
Public Function GetFoo() As Object
If AGlobalVariable Is Nothing then
Set AGlobalVariable = ...
End If
Set GetFoo = AGlobalVariable
End Function