I wrote a DLL in .NET and I want to access it in VBScript. I don't want to add it to the assembly directory.
Is there a way to point too the DLL and create an instance of it?
I just had to do this myself, my findings were:
Making types visible to COM:
Ensure your class is public, non-static and has a public default constructor i.e. not arguments.
Ensure your method is public, non-static.
Ensure you have the following set on your assembly - typically in AssemblyInfo.cs
[assembly: ComVisible(true)]
After building your DLL, from SDK command line run:
regasm yourdll.dll
This should respond:
Types registered successfully
If you get
RegAsm: warning RA0000: No types were registered
then you need to set ComVisible or have no public, non-static types.
From PowerShell
$a = New-Object -comobject Your.Utils.Logging
$a.WriteError2("Application", "hello",1,1)
From vbs
Set logger = CreateObject("Your.Utils.Logging")
logger.WriteError2 "Application", "hello from vbs",1,1
huseyint's answer was on the money, however, I wanted to add a little to it. Here is some sample code I used for this very issue, perhaps it can speed you along...
// bind a variabe to WScript.Shell
Set WshShell = CreateObject("WScript.Shell")
// define the path to the regasm.exe file
RegAsmPath = "c:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe"
// register the dll
WshShell.run "cmd /c " & RegAsmPath & " c:\temp\cbsecurity.dll /codebase /nologo /s", 0, True
// bind a variable to the dll
Set cbUtil = CreateObject("CBSecurity.Utilities")
I had included an IsAlive method in the dll...
Public Function IsAlive() As Boolean
Return True
End Function
...and could check that it registered correctly using the syntax:
//check if dll is available to your code
msgbox "cbUtil is alive: " & cbUtil.IsAlive
Hope this helps someone...
You can register that .NET dll with regasm utility by specifying /codebase parameter. This parameter is not encouraged to use with unsigned assemblies but it works when you can not put your assembly into GAC.
regasm your.dll /codebase
Please note that you should not change your .dll's path after this operation since it inserts this path into the Windows registry.
In case someone needs to debug/step-into the .Net dll that's called from VBScript only:
On the .Net dll project debug setup screen, set the "start external program" by browsing to the wscript.exe program (located in C:\WINDOWS\system32\wscript.exe).
On the "Command Line Arguments", set the file name and path location of the VBScript file (C:\Test\myTest.vbs). Make sure the vbs file and dll file are in the same location.
Finally, in the .Net project DLL source code just set the break point and hit the "start debug"
Not directly. You'll need a COM Callable Wrapper to any .NET library you'll calling from COM (and hence, VBScript). Therefore, you should either directly create a CCW to the DLL or you can create a CCW for a proxy DLL which provides generic methods to load a .NET DLL and provide methods for you that call the actual methods on the component and return the result. It's really not clean at all. So, in general, the answer is no.
Related
I am moving a classic ASP application from IIS6 to IIS7.5 and I am having troubles with COM dependencies.
This is the problematic code
SET o = Server.CreateObject("ClassName")
Response.Write "Returned object: " & TypeName(o)
result = o.SomeMethod()
The first line succeeds, the second line prints "Returned object: ClassName".
The third line ends with an error
Error: 429
Source: Provider
Description: Class not registered
I don't know, whether that is a 32 x 64 bit issue (the server is 64bit, the old one was 32bit). But I did set the "Enable 32-Bit Application" property of the application pool to True.
Is it normal that Server.CreateObject returns an object and it is the method call that actually fails?
We are using WIX script to register the COM classes (I did not do any modifications in this part).
I can find my class in the registry in Computer\HKEY_CLASSSES_ROOT\Wow6432Node.
I would appreciate any pointers, this drives me crazy.
You have got an instance of ClassName. No error on object creation and TypeName confirms it. So, the component is correctly registered.
But, does it reference another component which is used from the method you are calling? It seems a not controlled error raises from inside your class.
If I have a class library with an app.config file (I know it's not ideal, just bear with me for a moment) which has settings values created by using the projects Settings tab and accessed like this:
Public Shared Function GetMySetting(key As String) As String
Dim value As String = My.Settings.Item(key)
If value = String.Empty Then value = "Setting " & key & " not found."
Return value
End Function
I then retrieve the settings from an application like this:
sb.AppendLine("GetMySetting: " & Library.Settings.GetMySetting("SettingC"))
The settings from the app.config file of the library project are definitely not copied into the app.config file of the application but I can still retrieve the My.Settings from the libraries app.config.
So I added a GetConfigFileName function to the library:
Public Shared Function GetConfigFileName() As String
Return AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
End Function
and retrieved it in the application:
sb.AppendLine("Library Config File: " & Library.Settings.GetConfigFileName)
but that returns the application's config file.
How can I determine which .config file the library is reading from when it calls My.Settings...?
Or are they compiled into the DLL?
but that returns the application's config file. How can I determine
which .config file the library is reading from when it calls
My.Settings...?
By default, it will be always the main.exe.config.
Take a look at this for detailed answer
C# DLL config file for
more informations
You can use external config files. This article on MSDN
explains how.
EDIT
You're misunderstanding the situation, reread this line: The settings
from the app.config file of the library project are definitely not
copied into the app.config file of the application but I can sti retrieve the My.Settings from the libraries app.config.
You are correct. Your settings in the dll.config will not be copied automatically in the app.config.
Concerning the value that you are able to get from your dll, I am still looking for more official answer, but the answer seems to be:
the 'old' values (the ones you define at development time) are hard coded. If the
franework isn't able to access or open the config file it will use the defaults
instead. This will always happen if you use settings in a dll.
Take a look at this Settings.Default.<property> always returns default value instead of value in persistant storage (XML file)
Edited after reading comments.
I think I see what your after. The My.Settings will used the compiled values from your class libs settings as default values. I believe these are compiled in. You can reflect the source though to see if it is setting a defaultvalue attribute on them.
You can override these by setting the values in the main exe's application file. If the settings aren't in the exes file, then you will use the default ones you specified in your class libs.
You shouldn't care about the file name. Just assume the settings are either defaulted or were overridden. If you need to know if they were overridden, that's another issue.
I have a .NET COM DLL that I want to unregister. I do:
regasm.exe /u ConfigManager.dll
When I look with COM-ole viewer app I still see in type libraries section an entry for ConfigManager( specifies the path to ConfigManager.tlb there). How can I make sure I deregister for good any entries of ConfigManager.dll COM ?
I ask this because I have a nasty error where it seems that ConfigManager clients do not see some types from ConfigManager and want to make sure I deregister and register again ConfigManager
You just need a typelib registration utility. TypeLibs are not specific to .NET so you can find these kinds of ones anywhere.
Here's a simple one:
http://www.vbaccelerator.com/home/vb/utilities/Type_Library_Registration_Utility/VB6_Register_TypeLib_Utility.asp
I prefer to use TlbExp instead of the /tlb option of RegAsm to get a typlelib without automagically registering it. That way I can explicitly register (or unregesiter) the typelib.
I am building a DLL that is used by Office. When Office runs with it, I would like to identify where it is located. Is that possible?
ex. of code within the DLL when it is run within Office:
// should return C:\tmp\officeaddin.dll,
// currently C:\Program Files\Microsoft Office\Office 12
MessageBox.Show(Application.StartupPath)
The following should work even if running inside of Office:
Getting the path of the current assembly
(It basically boils down to Assembly.GetExecutingAssembly().Location, but see the link above for more detailed information.)
If it is a .NET library, you should use Assembly.GetExecutingAssembly().Location.
Application.StartupPath shows the path to the main app.
This works for me:
Environment.CurrentDirectory
So you could just set a string to it such as:
Dim location as String = Environment.CurrentDirectory & "\"
When the DLL loads, It calls DllMain with the instance handle. If you implement this function, you can then record the instance handle of the DLL. From this, you can then call GetModuleFileName.
In .NET this is taken care of for you. See this question and selected answer for details.
i worte a dll of com object
i registered it
where can i find this dll now in my machine
(when we register dll to where the nachine copy the dll)
and more question if i try to use this com object in powerShell everything thong work well
if i try to use it in javaScript i get exception
any idea??? why??
Registering a COM DLL does not copy the DLL. It just adds registry keys which COM uses to locate your DLL. For example, for every class a key "HKEY_CLASSES_ROOT\CLSID{your class ID}" is added. A lot of the time the path to your DLL is stored as the default value in a subkey such as "InprocServer32" (actual name depends on how your class is configured to be activated).
JavaScript cannot access COM objects, or even local files for that matter, because JavaScript is executed inside an isolated environment set up for security reasons.
As Richard Walters stated, registering a COM object does not copy it anywhere. Usually I am lazy and rather than looking up long GUIDs in REGEDIT, I search for the DLL's name using the Find feature.
Since you mentioned PowerShell, can I assume you are trying to use Javascript within the Windows Script Host? If so, knowing what the exception is might help. An example on how to do this though:
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.load("foo.xml");
Of course replace Microsoft.XMLDOM with information from your COM object.
The equivalent PowerShell would be:
$xml = New-Object -ComObject Microsoft.XMLDOM
$xml.load("foo.xml")