Use .NET Framework Libraries in 64bit assembly referenced from VBA7 in Excel - interop

I have a library written in C# that uses standard .NET framework libraries (System, System.Windows.Forms).
This library is COMVisible as well as its classes, I just have two classes:
- TestClass (a class with one method)
- TestForm (an empty form)
I registered the assembly as suggested here: C# COM DLL: do I use Regasm, or Regsvr32?
Then I went to my Excel Add-In and added a reference to the generated .TLB file.
I am able to create an instance of my "TestClass" and invoke its method without any problem, but when I try to create an instance of my "TestForm" it shows me this error:
Run-time error '-2147024894 (80070002)':
Automation error
The system cannot find the file specified.
According to the issues I saw when trying to get the class working, the problem is that one of the dependencies (I'm guessing System.Windows.Forms) is not being found by Excel.
How do I open a Form written in .NET from my 64bit Office add-in?
Thanks in advance

Below example may helps u how VBA7 code works in 64bit Office.
Adding into the 64Bit Office Addins may not be a problem, but when you try to use them in the VBA7,u will definetly experiance a problem.
Testing if weither using the 64-bit version(VBA7) of Office 2010:
#If Win64(VBA7) Then
Declare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong
#Else(VBA)
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#End If
If i am wrong reach me with the solution #kirantej#gmail.com
Hence, i am working on the same task too...:-P

Related

External DLL in VB6 with namespaces

I'm currently having some trouble with a VB6 application that needs to encode some text using the same encoding method available at .NET framework 4.5.
I've searched through the internet and found some functions that tries to do the encoding based in UTF-8, but it still doesn't match the 4.5 output.
Then I looked for a way to import the 4.5 framework DLL within the VB6 project. This is what I accomplished so far:
Private Declare Function dotNetUrlEncode Lib "System.Web.dll" Alias "UrlEncode" (str As String) As String
The problem is that the method "UrlEncode" it's inside the namespace "HttpUtility", "System.Web.HttpUtility.UrlEncode" and using the code above I cant access the method. I've tried changing it to look like the code below, but the problem persists, I cant reach the method UrlEncode:
Private Declare Function dotNetUrlEncode Lib "System.Web.dll" Alias "HttpUtility.UrlEncode" (str As String) As String
Private Declare Function dotNetUrlEncode Lib "System.Web.HttpUtility.dll" Alias "UrlEncode" (str As String) As String
Is there a way to reach the method UrlEncode inside "System.Web.dll"? Where am I going wrong?
Thanks for the help!
Best regards.
This will not work. The .NET DLLs contained managed code, which requires the .NET runtime. Your VB6 app can't call that code. Its process does not have the .NET runtime loaded.
You can only import functions from native DLLs this way. That's why it works for system DLLs included with the operating system.
The best solution would really be to consult the documentation and determine precisely how the UrlEncode function works. The internals of the implementation will not be documented, of course, but that doesn't matter. All you're interested in is the specification. Follow that same specification when implementing your own function if you cannot find a system function that has equivalent behavior.
If you absolutely needed to call .NET functions from a VB 6 application, it can be done. You will need to create a .NET wrapper that calls the framework-provided function and exposes in a COM-compatible manner using the ComVisibleAttribute. More information here, here, and here.

COMVisible class in VS 2010 assembly still not visible through com

I created a VS 2010 class library. Marked the assembly for Com Visibility. Signed the assembly with a strong key. Created my class, have my entry point method available.
The library works fine from a test project in C#.
I regasm the class library to gac, via:
c:\windows\microsoft.net\framework\v4.0.30319\regasm testdll.dll /tlb: testdll.tlb /codebase
Include the tlb file as a reference in my VB6 project. I find it through resources 'browse' so its there.
When i try to instantiate the class... its empty. the public method that should be available via the public class doesn't show.
Dim objTest as testdll.testclass
set objTest = new testdll.testclass
objTest.testmethod <--- this 'testmethod' doesn't display in intellisense... nothing does.
In addition i tried calling the 'testdll.testclass' via CreateObject, i get the error "ActiveX component can't create object"
Now i have other projects i've done COM visibility for and i've tried comparing the difference, but i don't see any. I can't understand why it isn't working.
Any clues??? tx very much.
Just use an interface... one you define or to use the [ClassInterface(ClassInterfaceType.AutoDual)]
there are comments online you can find that indicate not to use autodual, but if you control the complete usage of your library, it seems like an 'ok' way to go.
I tried all sorts of ways to simulate / understand why my one project didn't need an interface to be visible by an vb project, without success. i had originally thought perhaps possible that it was because that project implemented an IDisposable Interface (the ONLY interface used in the C# projects that is com visible) but that didn't turn out to be the reason. Anyway I don't want to waste anyone else's time on this. thanks for the responses.
this link provides ample information on the subject:
http://anturcynhyrfus.blogspot.com/2011/03/creating-com-visible-c-component.html

windows DLL issues

I'm having problems with an Excel VBA application that uses a C DLL. The DLL is always stored in the directory above the Spreadsheet and it's methods are called from within VBA using;
#If Win64 Then
Public Declare PtrSafe Function <function name> Lib "..\<dllname>" () As Long
#else
Declare Function <function name> Lib "..\<dllname>" () As Long
#end if
You can wrap these two files and their directory structure in a zip file, move it around windows installations (different versions and 32- or 64-bit) and it works fine except with one computer and we haven't a clue why. All we get is an error that the program can't find the dll at ..\ from the VBA method that called the dll method. Installing MFC100.dll solved a previous runtime error 53 problem which got us to where we are.
If you've any advice on how to solve this, or ideas on what to try, I would be very grateful,
James
VBA will tend to complain that it "can't find" a DLL if actually the issue is one of the DLL's dependencies is missing. I suspect that's the problem. Try (re-)installing the Visual C++ libraries. Or, open the offending DLL in Dependency Walker (or a similar tool) to find out exactly what it wants.
While your downloading dependency walker, download ProcMon to see where your VBA app is actually looking at runtime.
The problem was that we'd not installed the 64-bit version of the VS C++ redistributable, only the 32-bit version. Once this was installed, everything worked fine.

C++/CLI wrapper for C++ native dlls

I have native C++ dlls that I need to use in our group's new C# programs. I wanna create C++/CLI wrappers for native C++ dlls, so as to be able to import and compile them in C#.
What I need to know is how to load the dll file in the wrapper source file at the first place. Exactly the same thing that #using <...> does for MSIL, but for loading native C++ dlls.
And also, how will the objects and namespaces inside the dll become accessible then (synatically)?
EDIT:
I use
class __declspec(dllexport) radar
{
// declarations and definitions
...
};
to export my radar class from my radar.dll, and need to import it in a VC++(CLI) program like this: __declspec(dllimport) public class radar; so as to conduct it's definition into C#, but definitely I can't see radar in C#, because its not defined public in VC++(CLI). Even when I wanna use native dll's objects in VC++ dll's code, like radar pos1(); I get:
error C2512: 'radar' : no appropriate default constructor available
How can do this, having just the radar declaration at hand?
END EDIT.
Thank you!
It is automatic, you don't do this yourself. You specify the native DLL import libraries (.lib) in the linker settings for the C++/CLI project, Additional Dependencies setting. The linker links in a reference to the DLL name into the C++/CLI assembly. As soon as the C# code uses any of the managed types in the C++/CLI assembly, the CLR loads the assembly. Windows notices the native DLL references in the DLL and automatically loads them.
This can only come to a good end if Windows can actually find the native DLLs at runtime. Copy them into the build folder of the EXE project. That's awkward, you can do it with a post-build event or by adding them to the C# project with their Copy to Output Directory property set to true.

SetFileInformationByHandle in XP/2003 from Delphi?

The MSDN documentation for SetFileInformationByHandle refers to "FileExtd.lib on Windows Server 2003 and Windows XP". I managed to track down the library and .h file, which is available to download as the "Win32 FileID APIs 1.1" from:
http://www.microsoft.com/downloads/details.aspx?FamilyID=1DECC547-AB00-4963-A360-E4130EC079B8&displaylang=en
It appears the implementation is in the static .lib file - how can this be referenced/linked to a Delphi app? Is my only option to create a "C Dll" in Visual Studio and export the functions? And has anyone ported the .h file to Delphi header definitions?
C and C++ use lib files to provide the "stub" that the linker can use for a DLL function. The actual function implementation is in the DLL. Delphi doesn't use lib files; its external directive accomplishes the same thing. Therefore, you can usually ignore the "library" requirement in MSDN. The "DLL" requirement is still valid, though.
If the units that come with Delphi don't include an API function you want, then you have a couple of options:
Find someone else's code that declares it for you. A frequent candidate is the Jedi API units.
Declare it yourself.
interface
function SetFileInformationByHandle(
hFile: THandle;
FileInformationClass: TFileInfoByHandleClass;
lpFileInformation: Pointer;
dwBufferSize: DWord
): Bool; stdcall;
implementation
function SetFileInformationByHandle; external 'kernel32';
I don't know whether TFileInfoByHandleClass is already declared somewhere; you might need to declare that, too. MSDN includes function declarations, but sometimes lacks associated enum and constant values, so it's handy to have the Platform SDK headers nearby (so the download link in your question isn't totally useless).

Resources