|
Hi,
I made a com component in C# but I don't know how to call it from a VC++ environment(the steps to register it ,etc..)
Thanks
emmy
|
|
|
|
|
Hello meesho,
Just like a normal COM DLL or EXE, a .NET module which has been wrapped as a COM module needs to have its information written into the registry in order for the COM sub-system to locate it and load it into memory for a client.
REGASM.EXE
----------
This is achieved via the REGASM.EXE utility. REGASM performs similarly to the well-known REGSVR32.EXE utility which is used to register COM modules. REGASM uses the metadata contained inside a .NET assembly to generate COM-equivalent information which are then used to insert entries into the registry.
The entries written into the registry include the CLSIDs and ProgIDs of .NET classes which are exposed as COM classes. This registration process is important for COM clients in the discovery and loading process.
Call the REGASM.EXE utility inside the Visual Studio .NET command prompt as folows :
regasm <.NET DLL Assembly Name> /tlb
The "/tlb" flag commands REGASM.EXE to produce a Type Library File (.TLB) for the .NET Assembly. It is useful for your VC++ client to import.
In your VC++ code, you import the .TLB file using the #import keyword, e.g. :
#import "(TLB file path)";
GACUTIL.EXE
-----------
Next, for ease of discovery and loading by the .NET CLR engine, your .NET DLL Assembly -should- be registered into the GAC (Global Assembly Cache). This is not 100% required but will make life must easiler for your client apps.
In order that a .NET module be registered to the GAC, it needs to be digitally signed. This requires a Strong Name Key (SNK) file. You can create an SNK file using the "sn.exe" .NET utility.
Another step to take is to set the path of the SNK file in the AssemblyKeyFile attribute in the AssemblyInfo.cs file :
[assembly: AssemblyKeyFile("..\\..\\KeyFile.snk")]
To register an assembly into the GAC, we use the GACUTIL.EXE utility. For example :
gacutil -i <.NET DLL Assembly Name>
An alternative to using GACUTIL.EXE is to copy your DLL Assembly into a folder location that can be discovered by the .NET CLR.
Give it all a try, meesho. Let me know if you need further clarifications.
Best Regards,
Bio.
-- modified at 2:24 Friday 9th December, 2005
|
|
|
|
|
i have a question regarding article
Component-Based Development with Visual C#
By Wiley Technology Publishing
http://www.codeproject.com/books/0764549146_8.asp
now i want to have drag and drop support with web browser control, plz guide me which interfaces should i implement.
i have xml data in treeview control, now i want to design my own html page with xml data , how do i drag and drop xml element on web browser control
plz help me
fahad
|
|
|
|
|
Can any one tell me the good e-book or any book for learning ActiveX Programming with the combination of VB or C++.this should be usefull for begining level and also programable.
N.Rajakumar B.E.,
Application Developer,
|
|
|
|
|
Start with MS MSDN, in that go to Contents tab and "Inside OLE" partial book is available.
|
|
|
|
|
Guys,
I am an accomplished embedded coder, but not very adept with windows programming or COM. However, I have a quick command line program to write to make use of a seed2key dll.
The dlls prototype is..
API seed2key(char *seed, BYTE *key). I know this because I have the source code for it.
However, when trying to use the seed2key function in a C++ console app, the compiler thinks that the parameters should be of type LPSTR and LPBYTE respectively.
Unfortunately I have no idea what these are. I have a 16 byte array carrying the seed, that i need to pass to this function.
How do i create an LPSTR from that?
Does anyone have any idea what parameters it is actually after, and can provide me with a way to do so?
Many Thanks to anyone who can help.
Paul.
|
|
|
|
|
LPSTR = long pointer to string, ie char *
LPBYTE = long pointer to byte, ie BYTE * -> ie unsigned char *
Do you have the code snippet that's failing to build?
|
|
|
|
|
Thanks for that! I couldnt find that information anywhere on the web!
The code snippet is below. It is VERY rough as I am hacking around to get a solution.
int main()
{
BOOL procReturn = 0;
HINSTANCE dllHandle = NULL;
KWP_COMPUTEKEYFROMSEED pSeedAndKeyFunc = NULL;
dllHandle = LoadLibrary("seed_inv.dll");
if (!dllHandle)
{
cout<< "Failed to Load dll" << endl;
}
else
{
cout<< "DLL loaded OK" << endl;
}
if (dllHandle)
pSeedAndKeyFunc = (KWP_COMPUTEKEYFROMSEED) GetProcAddress(dllHandle, "seed2key");
if (!pSeedAndKeyFunc)
{
cout<< "ProcAddress Failed"<
|
|
|
|
|
This should work:
BYTE seed[16] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x00};
status = (*pSeedAndKeyFunc)((LPSTR)seed,key);
it's probably looking for the null terminator on the string.
|
|
|
|
|
Fantastic. That seems to work a treat.
However, on the inside of the dll, the first function is this..
API seed2key (char *param, BYTE *key)
{
BYTE seed[16];
DWORD i, retLen, seedLen;
BYTE *scanPtr;
i = 0;
scanPtr = strtok(param, " \t\n");
while (scanPtr && i < 16) {
seed[i] = atoi(scanPtr);
scanPtr = strtok(NULL, " \t\n");
i++;
}
seedLen = i;
seedToKey (seed, seedLen, key, &retLen);
return (retLen);
}
the while loop iterates once through correctly, but on the second time the string tokenizer returns 0x0000000 into scanPtr.
When you hover over it in VS, the tooltip says. [scanPtr = 0x00000000 <bad ptr="">].
The above section of code seems to suggest that it is actually requiring a string with the delimeters " ", tab and newline.
Rather confusing - although seemingly a different issue, any ideas?
Thanks for the previous posts!
Paul.
|
|
|
|
|
I'd see if the seedToKey function their calling is exported, it seems like a safer function to use. Otherwise, I'd probably change this:
BYTE seed[16] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x00};
to
char seed[] = {0x1,'\n'...,'\n',0xf,0x00};
You can also eliminate the cast that way.
|
|
|
|
|
Hi All...
I have set up an environment in which a ASP page create a object of COM component deployed in COM+ environment. COM Componenet is launched in a dedicated process(DLLHost). In settings of COM+ application, I have set Enable Idle ShutDown Time to 3 minutes.
But DLLHost.exe does not terminates after 3 minutes. It terminates after around 20-25 minutes.
On windows 2000 DLLHost.exe does not terminates.
Can anyone explain me why this is so and what is the difference between windows2000 and windows server 2003 environment.
Suraj Gupta
|
|
|
|
|
In WinXP SP2, there is a service called "DCOM server process launcher" run via svchost.exe. Today I noticed in Process Explorer that there is a "iexplore.exe" process running as a child of this svchost.exe, and tracking back how I started this instance of Internet Explorer, I had clicked on "2 new email messages" in the MSN Messenger (6.2). This is very interesting and I dont know why internet explorer does not show up as a child process of MSN Messenger itself. Anyone any ideas?
I was curious, I then attached windbg to this svchost.exe and put a breakpoint on NtCreateProcessEx, and you know what, the breakpoint is hit even if I start IE from the Windows Explorer shortcuts. Infact, the breakpoint is hit for every process that I start from windows explorer. The difference, however, is that the process is still created as a child of explorer.exe and not as a child of svchost.exe when I start from Windows explorer.
The questions I have are:
1. How exactly does this DCOM server process launcher work? Are there any architecture overview documentation?
2. How do you communicate with it to start a new process? Which COM interface to use?
3. What decides on who is going to launch the new process? svchost or calling process?
I'm not sure if this is good forum to ask this question, if it is not and you know an alternate forum, please let me know.
thanks!
--s
|
|
|
|
|
Further, on WinXP SP1, this is what I notice when I click on "1 new email message" in MSN Messenger:
1. When I have an instance of IE already running, the new IE window is created off this process.
2. If there are no instances of IE running, a new "iexplore.exe" starts under "svchost.exe -k rpcss" service.
Anyone knows what is happening here?
thanks!
|
|
|
|
|
Not sure if this should be here or in the C# forum but here goes. I want to create an out-of-process COM component (like an ActiveX exe in VB6) in C# - does anybody know how to do this? I've created in-process COM component with no problems. Any ideas/links would be most appreciated.
Cheers
|
|
|
|
|
Hello london_ste,
I've been researching into this a few months back. Basically, you would need to create a .NET factory class (contained inside a DLL Assembly) that exposes methods that internally instantiate .NET classes from .NET Exe Assemblies. Let's call this the "factory" assembly.
This factory assembly will be wrapped up in a COM-callable wrapper via tlbimp.exe and Regasm.exe. It is your gateway to the creation of .NET classes housed inside .NET Exe Assemblies.
.NET Activation/Refletion or Remoting are techniques that can be used to create an instance of a .NET class housed inside a .NET EXE assembly.
The special thing about Remoting is that is can be used to instantiate a class from a running EXE application whereas Activation/Refletion loads an Assembly (DLL or Exe) and instantiates a class from the loaded Assembly module.
An example of a creation method can be fashioned as follows :
public object CreateInstance_ByActivation(string strAssemblyName, string strTypeName);
An unmanaged client (written in C++, say) can call this method as follows :
VARIANT varRet;
...
...
...
IFactory -> CreateInstance_ByActivation
(
bstrAssemblyName,
bstrTypeName,
&varRet
);
the object will be returned via the VARIANT "varRet". "varRet" will contain either an IUnknown pointer or an IDispatch pointer.
I'm planning to write an article on this in the future, watch out for it
Best Regards,
Bio.
|
|
|
|
|
Hi Lim,
Thanks for replying. But to be honest I'm not sure I understand. So what you are saying is wrap the exe in a DLL? and access that? But how is that out-of process? Or do you mean the DLL can instantiate and call directly into the exe which will be runnig outof-process ad somehow hold onto the reference to itso we can call more methods on the external exe?
Do you have any good links on Remoting which may help me understand more... Or any sample code you have which will allow me to work out wahts going would be appreciated....
|
|
|
|
|
Hello london_ste,
>> Or do you mean the DLL can instantiate and call directly into the exe which will be runnig outof-process ad somehow hold onto the reference to itso we can call more methods on the external exe?
Yes, this is what I mean. This DLL is what I refer to as the "Factory" DLL. It is also a .NET Assembly (a class library). Hence we will be working with at least 2 .NET Assemblies : the "factory" assembly and the .NET Exe Assembly which supplies the class that we want to expose to an unmanaged client.
This is how it works : an unmanaged client first talks to the "factory" assembly DLL through COM interface methods that are wrapped in a COM-Callable Wrapper. Let's call this interface the "factory" interface. Internally, the "factory" interface method performs the actual instantiation of the .NET class from the .NET Exe.
An example of such a "factory" method is :
public object CreateInstance_ByActivation(string strAssemblyName, string strTypeName);
The "factory" interface method can do the instantiation via Activation/Reflection or Remoting. After instantiating the .NET class instance (in the .NET Exe), the "factory" interface method delivers the .NET object directly to the unmanaged client by its return value (of type "object", which is translated into an "out" VARIANT parameter by COM interop).
An unmanaged client (written in C++, say) can call this method as follows :
VARIANT varRet;
...
...
...
IFactory -> CreateInstance_ByActivation
(
bstrAssemblyName,
bstrTypeName,
&varRet
);
The .NET object (housed in the .NET Exe Assembly) will be returned via the VARIANT "varRet". "varRet" will contain either an IUnknown pointer or an IDispatch pointer depending on how the class in the .NET Exe is attributed. You would retrieve the interface pointer by using the usual variant macros and functions, e.g. :
if ((V_VT(&varRet) != VT_EMPTY) && (V_UNKNOWN(&varRet) != NULL))
{
*ppTargetObjectUnknown = V_UNKNOWN(&varRet);
(*ppTargetObjectUnknown) -> AddRef();
}
Note that after the .NET Exe Class object has been delivered to the client this way, the "factory" is no longer needed. The client interacts with the object directly. This can be in the form of IDispatch::Invoke() or, if the client has the interface signature of the object, in the form of direct interface method calls (but QueryInterface() must be called on the returned IUnknown pointer first).
With several more developers recently asking for essentially the same information, I think I may want to write my article on this as soon as possible.
Concerning Remoting, there are many good introductory articles in CodeProject. I do recommend one written by me last year :
Simple but potentially useful example of .NET Remoting
http://www.codeproject.com/csharp/ProcessActivator.asp[^]
and
A Simple But Useful Example of .NET Remoting Part 2
http://www.codeproject.com/csharp/ProcessActivator2.asp[^]
Contact me again if you need further clarification.
Best Regards,
Bio.
-- modified at 4:13 Friday 9th December, 2005
|
|
|
|
|
I'm a beginner of COM. I just saw some sample codes:
DictionaryObj.cpp
<br />
extern "C" const IID IID_Dictionary = <br />
{ 0x54bf6568, 0x1007, 0x11d1,<br />
{ 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} } ;<br />
I don't understand the purpose of extern "C".
Since IID_Dictionary will not be exported, why to use this prefix?
Thanks.
|
|
|
|
|
The IID has to be visible across all .obj files that are using it.
Say IID_IDictionary is defined in fileOne.cpp (which when compiled generates fileOne.obj)
And in FileTwo.cpp you are referencing IID_IDictionary, the linker will error out unless the IID has the extern "C", as this extern "C" basically tells the linker that the IID is defined in another obj file.
Marco M.
|
|
|
|
|
Hi,
Problem Context: We are writing a COM component which is used in web-service.
Problem Facing : Accessing a COM component from ASP page or any scripting language is what we all know. But we wish to call web-services from a COM component, which does background processing and is suppose to issue HHTP request or somehow able to communicate with web-server.
The COM component will not have any user interface.
Regards,
Amol B. Ravatale
|
|
|
|
|
|
I'm using the OleDbConnection object to retrieve the contents of an
Excel Worksheet as a DataSet. This works fine when testing the
MyExcel.GetMonthly() method call.
When I call MyExcel.GetMonthly() from a Serviced Component, it bombs.
Code snippet:
OleDbConnection cn = new OleDbConnection(CnString);
cn.Open(); <-- Error occurs here
In an effort to isolate the problem I created a new class and called
MyExcel.GetMonthly() from it. Without ServicedComponent inheritence it
works fine. With ServicedComponent inheritence it crashes with:
A condition has occurred that indicates this COM+ application is in an unstable state or is
not functioning correctly. Assertion Failure: !m_punk
Server Application ID: {6E4E5709-D807-46DD-819E-2B3D150FC547}
Server Application Instance ID:
{C73018C7-1BB0-4DB2-A9DB-4D9E22521507}
Server Application Name: MSRBLL
The serious nature of this error has caused the process to terminate.
COM+ Services Internals Information:
File: d:\qxp_slp\com\com1x\src\comsvcs\jit\jit.cpp, Line: 858
Comsvcs.dll file version: ENU 2001.12.4414.258 shp
Any thoughts?
|
|
|
|
|
Guess I'll answer my own post
To ways to solve this problem:
1.) Put the assembly in the GAC
2.) Put the class that works directly with Excel in it's own
Class Library project. It doesn't need to inherit from ServicedComponent,
only the rest of the Data Acess Layer needed COM+.
<signature>
It's good to be alive
|
|
|
|
|
I use a MFC client program and an ATL DCOM server. The ATL Dcom server uses a hidden window to send back events to my clients. In my MFC-program I set up an Event sink using the "TEventHandler" template class.
The event sink is created in MFC-ui thread, I don't create any other new threads.
In the eventsink I allocate/free dynamic memory and store this in static pointer. At some point in MFC-UI thread I also allocate/free and store data at the same pointer.
At frequent times my program crashes and gives ACCESS VIOLATION. (On some machines it never crashes ...)
Is this because the Eventsink and the MFC UI-thread can be seen as different threads. (although I don't create any new.)
If so,would it help if I protected my data to be used in both threads using a lock,... Or do I have to allocate my memory in the eventsink in private heap (is the problem that new/delete are not thread safe) ?
Thanxs,
-- modified at 11:46 Saturday 26th November, 2005
|
|
|
|
|