|
Hi Guys!
I'm novice in DCOM and my question will be very easy.
I'm created COM-server and its COM-client. I can successfully run both on the same machine and successufully run
on the separate machine (with modification in dcomcnfg). The code is not changed when remote running.
I used the follows (it works fine):
IEncoder * pEncoder;
HRESULT hr=CoCreateInstance(CLSID_Encoder,
NULL,
CLSCTX_SERVER,
IID_IEncoder,
(void **)&pEncoder);
I'm trying to specify exactrly on which machine COM-server should be run using the follows:
WCHAR *wszMachineName=L"STAR\0";
COSERVERINFO srv;
ZeroMemory(&srv,sizeof(srv));
srv.pwszName=wszMachineName;
MULTI_QI qi;
HRESULT hr=CoCreateInstanceEx(CLSID_Encoder,
NULL,
CLSCTX_SERVER,
&srv,
1,
&qi);
This returns E_INVALIDARG.
What should I do to remotely invoke my COM-server from another machine using CoCreateInstanceEx() ?
Yours sincerely,
Alex Bash
|
|
|
|
|
Have you defined _WIN32_DCOM in your client? Also, you might want to set the MULTI_QI (qi in your case) memeber pIID to the address of the interface you are requesting to be returned and then try calling CoCreateInstanceEx.
Hope this helps.
|
|
|
|
|
Hello,
I have been trying to compile the sample code that comes with "Insdie OLE". Although the code compiles but when i try to run it. It asks for a inole.dll. which i cant find anywhere with the sample code. Can anyone help me with this. Thank you
|
|
|
|
|
Help, guys!
I'm novice in COM and my question is very easy.
I've created my first COM-server (say, Encoder that have produced files Encode_i.c and Encode.h).
Now, I'm writting COM-client for my COM-server. I've created new project (Simple Win32 application), copied
Encode_i.c and Encode.h into project with my COM-client. When I try to compile COM-client, I got the follows:
c:\home\encodeclt\encode_i.c(50) : fatal error C1010: unexpected end of file while looking for precompiled header
directive
Error executing cl.exe.
EncodeClt.exe - 1 error(s), 0 warning(s)
What should I do?
Yours sincerely,
Alex Bash
|
|
|
|
|
Read the C++ FAQ here on CP
You need to adjust the project settings for that particular file so that it does not use precompiled headers, or alternatively, #include it into stdafx.cpp.
Steve S
|
|
|
|
|
I have been given an IStorage pointer as part of a drag and drop operation and I would like to extract the contents into a block of memory. Whats the best way to do this? So far I have used the following method which seems to work but looks a bit naff. Anybody got any comments to make?
<snippet>
<br />
VOID ExtractStorageData(IStorage *pStorage)<br />
{<br />
<br />
WCHAR fspec[MAX_PATH];<br />
CreateTempFilename(fspec);<br />
<br />
<br />
IStorage *pNewStorage;<br />
pStorage->StgCreateDocfile(fspec,<br />
STGM_CREATE | STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,<br />
0,&pNewStorage);<br />
<br />
pStorage->CopyTo(NULL,NULL,NULL,pNewStorage);<br />
<br />
pNewStorage->Release();<br />
<br />
<br />
BYTE buffer[65535]<br />
<br />
HANDLE h=OpenTempFile(fspec);<br />
ReadTempFile(h,buffer,sizeof(buffer));<br />
CloseHandle(h);<br />
}<br />
Systems AXIS Ltd - Software for Business ...
|
|
|
|
|
You can read directly into memory without creating tem file:
Instead of "StgCreateDocfile":
1)CreateILockBytesOnHGlobal
2)StgCreateDocfileOnILockBytes
then get a HGLOBAL (GetHGlobalFromILockBytes) and read it
HTH
Edward
|
|
|
|
|
I have a question regarding COM objects.
I have created a COM object (dll) that is used by an ASP page. The thing is that when multiple users call the page with COM, the object can not process multiple requests simoultaneusly.
Why is that ?
I'm using VC++ 6.0
|
|
|
|
|
Is your object STA?
Steve S
|
|
|
|
|
Now my object is Free with Free threaded marshaller.
It works from a .exe test program, but it's still not working from the ASP page.
I think it's something related to ASP.
|
|
|
|
|
Probably. You might do better posting in 'Web Development'
(and I expect the clickety-police to be along any second now...)
Steve S
|
|
|
|
|
Hi,
How to Use C++ code in VB???
please help me inthis regard
Imran
|
|
|
|
|
An easy way to do it is to create OLE automation compatible COM servers.
--
<british-accent>Pass the jam, would you?
|
|
|
|
|
And a good, fast way to create Automation-compatible COM Servers is to use ATL.
- Bio.
|
|
|
|
|
Indeed!
--
<british-accent>Pass the jam, would you?
|
|
|
|
|
|
|
COM is Microsoft's binary object model. It is an interface based programming architecture along with a set of runtime services.
|
|
|
|
|
|
I'm calling an delphi ocx control from a visual c++ application (not MFC).
(CoInitialize, CoCreateInstance,...and so on). ActiveX functions are complete available.
I try now to connect my c++ window to this activeX, so that all activeX routines will paint there.
How can I do this ? (any sample code ?)
Do I have to write a complete OleContainer or will some only simple routines work as well ?
PS:
The ocx does some polyline paint actions, which I will save via activex routines.
Thanks
|
|
|
|
|
I was making a program which shows u the streams and storages within a compound file. Can anyone tell me how to delete the root storage object. Since normally you delete any substorage using its parents pointer.....but how to delete the root storage object which has no parent.
|
|
|
|
|
Simple. You delete the entire stg file. It's analogous to deleting the root directory on a hard drive. The only way to delete it is to remove the partition on which the root directory is located.
--
<british-accent>Pass the jam, would you?
|
|
|
|
|
Hello everyone. Before being handed this project I have never worked with COM besides as an ActiveX user in VB, but thankfully I had a good MFC/C++, SQL Server background. Now I am responsible for the maintenance of a very large 3 tier application. After complaining to my boss I was not the right guy for the job (and he not caring very much), read a couple of books, did the tutorials, and done already quite a bit of debugging and fixes to the application. Backend is SQL Server 2000 (140 tables exposed through 400+ stored procedures, app never does SQL queries), middle tier is 28 components in a COM+ application and a MFC GUI, also some ATL services and device drivers involved, all which talk to the middle tier.
The software shop that originally did this product closed down and left us the latest version with many issues. I have solved most of them. We where having performance problems (very slow GUI, some deadlocks) so I ran some traces and found out that stored procedures where taking forever to execute - there where way too many indexes – about on everything. Doing things right (in my opinion) I was able to take the execution of the 100 longest running queries down from over a minute to 11 seconds. Watching the execution plan of the most commonly executed stored procedures, the indexes created where very badly chosen. I dropped around 100 non-clustered indexes and created a few, hand picked ones. Of course insert and updates are working very well now. Also the GUI is very usable now, from taking 10 or more seconds to change a screen or fill up some text boxes to almost instantaneous response, as it should be and was before this version.
Everything seemed fine until I ran it in a test computer. Then hell broke loose .
What I found out is that, just by dropping the non-clustered indexes, a call to a method in a component which calls a stored procedure is causing an ADO time out (ADO error -2147217871 ‘Execution aborted because a resource limit has been reached; no results have been returned’). Before dropping the indexes the call ran fine. If I go to the Com+ application, choose that component and change transactions from required to supported, the problem ‘goes away’ and calling the same method on the same component takes a few seconds. Changing back transactions being to required brings back the problem. I’ve already debugged and jumped to the component where the call is done and the call fails when the stored procedure is executed in ADO, so it is not a problem of the code of the component but somewhat related to Com+ and MTS configuration (or the component use of them), from what I can guess with my limited knowledge and experience.
The stored procedure is quite a complex one which creates a few temporary tables and then builds the returned records from them. In both situations, running the query the component runs in query analyzer, with the same user and against the same server, executes in a few seconds as it should. With the indexes dropped, the query runs FASTER than before.
In brief: before dropping the indexes, the call to the method ran with no problem both with transactions required and supported. After dropping the non-clustered indexes, the call to the method times out when transactions are required, and runs correctly when admited.
My MTS/COM+ and transaction knowledge is very limited, as you can guess – I have no practical knowledge in the field, just checked some books and debugged/modified the COM objects in this application. From what I have said above I can suspect some deadlock/race situation happening when COM+ transaction is happening, but I do not see how this is happening – this is the only call happening at the time, and it calls just one stored procedure. If I change the ADO command timeout, the time until I get the error just changes to reflect this – tried leaving the query running for as long as 10 minutes (which of course, anything over 30 seconds is very unacceptable).
Hope I explained myself well enough. Any help suggestions on how to tackle this problem would be very appreciated.
Thanks,
Juan Miguel Venturello
Edit: after a few hours of playing around, there is just A FEW indexes which I drop and causes the problem why is this????
|
|
|
|
|
Hi,
I am using a third party COM component that fires events when a certain operation has occured, like operation complete event is fired.
now i want to continue the work after the operation has been completed. i.e after the event has occured.
so i did this way... i put a bool value in the sink that is set to false when the completion event occurs.
and in the clin
CSink::OnCompleteTask(long code)
{
..
bTaskComplete = FALSE;
}
and at the place where i am calling the method.
pInterface->CopyFile(....); //this is asyncronouse operation.
while(CSink::bTaskComplete);
... it come here after the copy is complete
but the problem is that this thread is getting locked.
no events comes.???
why and how do i avoid it.
thanx.
Tech.Support : Mam, is your pc running under windows?
Customer : No actually its close to the main door.
|
|
|
|
|
Hello Prakash,
Your problem sounds like a typical Apartment-Threaded-Model COM Server/Client issue. I have provided a possible solution (jump straight to point 11 for the solution if my write-up below gets too boring) as well as an analysis of the situation :
1. Your application as well as the 3rd Party COM component is most probably Apartment-Threaded-Model based. Please let me know if this is the case.
2. When the following code is executed :
pInterface->CopyFile(....); //this is asyncronouse operation.
the 3rd party component probably starts or goes into another thread to perform its lengthy operation.
3. When the component has completed its operation, it must fire an event to your app to indicate completion of task. You have set this up by defining the CSink::OnCompleteTask() function and hooking this function to the component's connection point.
4. Everything is fine up to here. But why does your application (more precisely, the thread that calls the CopyFile() method) hang up ? Why does the CompleteTask event not fire ?
5. Quite simply, it's the endless while loop that is causing the problem :
while(CSink::bTaskComplete);
I'll explain this next.
6. When the 3rd Party COM component has completed its task, it will need to fire the CompleteTask event. This is done by CALLING the appropriate event handling function (in your case, this is the CSink::OnCompleteTask() function). The 3rd Party COM Component will already have a pointer to this function earlier on when event handling are setup.
7. Now, the very important thing is that the 3rd Party COM component will not be able to call your event handler function (CSink::OnCompleteTask()) directly. The call to the event handler function must be SERIALIZED. That is, the call request must be put into the message queue of the client application.
8. This serialization is done to ensure thread-safety and that the private data of the 3rd Party COM Component is always intact and not subject to random modification by threads running in your application.
9. Now, when the call request (to your event handler CSink::OnCompleteTask()) is put into the message queue of your app, the message queue must continue to pump in order that the call request gets executed.
10. Due to the fact that you are in a constant while loop, not only will the call request never get through, your application's GUI will also freeze up (if the thread that calls CopyFile() is also the main GUI thread).
11. To resolve the problem, try putting in a simple "make-shift" message pump after your call to pInterface->CopyFile(...) as follows :
MSG msg;
// Dispatch all windows messages in queue.
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage(&msg);
if (CSink::bTaskComplete == FALSE)
break;
}
The above message pump will ensure that the 3rd Party COM Component's call request to your event handling function will get through. Because of this, the CSink::OnCompleteTask() function will be executed and CSink::bTaskComplete will be set to FALSE.
Once CSink::bTaskComplete is FALSE, we will break out of our while loop.
12. Give the above code a try, Prakash. And let me know how things turn out.
Best Regards,
Bio.
|
|
|
|
|