|
Hello,
Application
-----------
I've created a multi-tier application. Its architecture is:
On client machine --> the client application is an ActiveX EXE component (VBasic).
On server machine --> some COM+ server applications and a SQLServer database.
Use Case
--------
CLIENT1
--> asks SQLServer database for an object (= a row in objects table).
The state of this object is stored in a storage file.
--> if the object can be check out, it means nobody else have checked out the object,
the server will set the objects.checkedoutby = ClientID and will copy the stg file
in a shared folder on server machine.
CLIENT2
--> tries to check out the same object
--> the server must know (??? - MY QUESTION IS ABOUT THIS POINT) if the CLIENT1 application
is still running or a crash has occured and CLIENT1 was not able to check in the object.
Remarks
-------
1) CLIENT2 will receive a copy of the storage file if CLIENT1 is still running
2) CLIENT2 will have the possibility to restore the storage file from
an older version if a crash occured in the CLIENT1 application.
3) Many clients can log in using the same account (user name and password)
4) There can be more than one instances of the application on the same client machine
My solution
-----------
My solution is to create an instance of an "watchdog" ActiveX EXE on the client machine
when the client application is started. This "watchdog", from time to time (5 minutes by example),
will modify the value of a date field named NotificationDate in database.
When the client application shuts down, the "watchdog" will stop updating that field.
The stored procedure responsible for check out will use the value of NotificationDate field
to decide whether the CLIENT1 application that use this object is still running or a crash has occured.
Questions
---------
1) Is there a pattern for this problem?
2) What about my solution?
10x,
Ovidiu
|
|
|
|
|
Hi,
I'm rather new to COM. I was working with the ATL/COM wizard in VC++ and I tried to overload an interface method. But the wizard doesn't let me do this. It says that the name conflicts with an existing name. Is there any way I can actually overload an interface method in VC++?
Thanks in advance
|
|
|
|
|
you MUST implement an interface in the class where it is used as the base interface..if u dont implement an interface it will not compile and ask for the implementation of the interface in the inherited class..
so here are the steps...
1. make a new class..
2. make it inherit from the Interface u just made..
3. Implement all the methods that the interface has got, in the class..if u dont want to implement a method, make it return E_NOTIMPL!
|
|
|
|
|
I'm not sure if this is the right forum but please tell me and I hope you understand my english....
My problem is that when using a deskband I wnat to know if the band is beeing destroyed because is changed form docked to floating and so on or because the user has closed it....Does anyone understand me and maybe know the solution...
///Mårten
|
|
|
|
|
|
Can anyone suggest a way I can return my COM object's module instance handle (HINSTANCE) to my client?
Am I going to have to use a VARIANT?
The reason I wish to do this is to get a handle on my COM object so I can access its resources like strings and icons.
The alternative is for my client to just access my COM object's container DLL but then my client would have to determine the DLL name by calling a suitable method. This sounds a bit of a "hack" to me though, compared with accessing the resource via a returned module instance handle.
"The folly of man is that he dreams of what he can never achieve rather than dream of what he can."
"If you think education is expensive, try ignorance."
|
|
|
|
|
Just exporting it by a long property will be enough. You don't need to use VARIANT .
rechi
|
|
|
|
|
Hi all,
Can anyone tell me how I an find out what a specific HRESULT error code means? The specifics are that I'm trying to set the text of a Bookmark in Word (using C#), but I keep geting a COMException which only tells me that the attempt to set Bookmark.Text failed, and supplies an errorCode. I'd like a bit more info - i.e. why it failed
are the Office Automation errorcodes documented anywhere? I can't seem to find anything on MSDN.
TIA,
Pete
|
|
|
|
|
hello!
is there any way to get remote client's icon (from its executable file for example) by my server (com application)?
thanks in advance.
max da man
|
|
|
|
|
Maybe you can make the client to return to the server a picture object ( see IPicture OLE implementation in MSDN).
|
|
|
|
|
using typelib read name of executable/dll and try LoadResource (icon)?
Just a guess..
|
|
|
|
|
What is COM and what do I use it for ?
I am programming in Visual C++ 6.0 - do I need to know what COM is ? eek:
can someone explain it to me like if I am a 3 years old child ?
thanks alot
Sendel
|
|
|
|
|
|
thanks
Sendel
there is no spoon
|
|
|
|
|
Hi!
I'm new to posting here, but I wanted to start out with an annoying
feature that was bugging me. I get to do a lot of the weird programming
assignments.....
I've got a ATL/COM Service that has one Simple ATL Apartment object. It takes a flat
file record and converts it into a one row recordset with appropriate columns.
It has a method to pass a detached recordset back and forth, such as this:
[id(2), helpstring("method ReadRecord")] HRESULT ReadRecord([in, out] VARIANT *iRetVal, [out, retval] IUnknown **ppRecordset);
STDMETHODIMP CGenericObj::ReadRecord(VARIANT *iRetVal, IUnknown **ppRecordset)
It works perfectly fine, except when you get into the debugger, and only once you get
out of the raw_ReadRecord.
First-chance exception in Generic.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.
But, everything works fine, even in release mode. When I don't detach the recordset, the message does not surface. When the object is passed back in through:
STDMETHODIMP CGenericObj::WriteRecord(IUnknown *pRecordset, VARIANT *iRetVal)
It does the same thing.
The code to generate it:
_RecordsetPtr m_pRs;
m_pRs.CreateInstance(__uuidof(Recordset));
(read field loop)
m_pRs->Fields->Append(_T((LPCSTR)pField.sExternalName), lEnum, lFieldSize, adFldIsNullable);
(read field loop end)
_variant_t vNull(DISP_E_PARAMNOTFOUND,VT_ERROR);
m_pRs->Open(vNull,vNull,adOpenForwardOnly, adLockOptimistic, adCmdUnknown);
m_pRs->AddNew();
(read file field loop)
m_pRs->Update();
*ppRs = m_pRs.Detach();
Just curious what you coders think....
|
|
|
|
|
What's the exception code ?
|
|
|
|
|
Heh, as it reads in the question itself (First Chance exception....), only unless you turn off automatic handling of that exception, it just does a print to the debug window....
Ah well...perhaps I didn't build the object right...
|
|
|
|
|
"First chance exception in ... : Microsoft C++ Exception" means a C++ exception is thrown but not catch. Try to wrap up your method call in a try / catch statement, and catch a _com_error exception. Take a look at the error code.
|
|
|
|
|
Its just an access violation in Kernel32 once the raw_ function loses scope, which means it could be anything, so I think I'll just drop it. Ah well, I've got to get back to DOS programming now....
|
|
|
|
|
I can create MULTIPLE internet shortcuts by the following code
CComQIPtr<IUniformResourceLocator, &IID_IUniformResourceLocator> m_spURL;
CComQIPtr<IPersistFile, &IID_IPersistFile> m_spPF;
CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*) &m_spURL);
if (m_spURL == NULL) return E_FAIL;
m_spPF = m_spURL;
if (m_spPF == NULL) return E_FAIL;
m_spURL->SetURL(strUrl1, 0);
m_spPF->Save(strFile1.AllocSysString(), TRUE);
m_spURL->SetURL(strUrl2, 0);
m_spPF->Save(strFile1.AllocSysString(), TRUE);
m_spURL->SetURL(strUrl3, 0);
m_spPF->Save(strFile3.AllocSysString(), TRUE);
But trying to load more than one shortcuts will fail
hr = m_spPF->Load(strFilename1.AllocSysString(), STGM_READ);
LPSTR lpTemp1 = NULL;
hres = m_spURL->GetURL(&lpTemp1);
if (SUCCEEDED(hres))
{
IMalloc* pMalloc;
hres = SHGetMalloc(&pMalloc);
if (SUCCEEDED(hres))
{
pMalloc->Free(lpTemp);
pMalloc->Release();
}
}
hr = m_spPF->Load(strFilename2.AllocSysString(), STGM_READ);
DWORD E = GetLastError();
Did I forget release something? is there something like "close" I have to call? Of course, I can release both interface
and create a new one, but why I can save multiple urls? also, Is createinstance consider an expensve function call?
Thanks for help!
Shawn
|
|
|
|
|
Hi All,
I'm working on a small project which converts PowerPoint documents to SWF. The convertor contains of two parts, the PPT extractor and the SWF composer. The extractor basically traverses the presentation's object model and extracts information that it understands and stores them. The problem I'm getting is when accessing certain objects (such as _Presentation->_Slide->Shape->Vertices or _Presentation->_Slide->Shape->Adjustments) using the raw interface I got E_ACCESSDENIED return code. Here's an excerpt of the code:
// Env: Windows XP, Office 2000
#import "MSO9.DLL" auto_rename
#import "VBE6EXT.OLB" auto_rename
#import "MSPPT9.OLB" auto_rename
using namespace PowerPoint;
...
PowerPoint::ShapePtr aShape = ...;
VARIANT aVertices;
HRESULT hRes = aShape->get_Vertices(&aVertices);
And now hRes is E_ACCESSDENIED. This happens to some other objects too. I've read some MSDN articles talking about Office automation is unsupported etc. So my questions are, how should I deal with these Access Denied errors? Does this look like a setting problem, or is it VC++? Will this become better if I use VB? The reason I use VC++ is I want to make the extract and the composer one single program. I'm not fluent in VB but if I make sure this could be solved in VB then I'd definitely like to try it. Any suggestion is appreciated!
Thanx, and Best,
Darrel
|
|
|
|
|
I have a com dll written in C++ which is used in asp applications. The dll contains only one com object. There are static (global to the process) data objects within this dll. Obviously, I only want to initialize these static objects when the dll is first loaded.
However, IIS seems to be reloading my dll everytime the com object is created and used in an asp page.
|
|
|
|
|
The proper way to do it is to make your server a service, if your objects need to have some context setup once per session. The answer to your question is to return allways S_FALSE from DllCanUnloadNow. In case you are using ATL you can achieve this by having a CAtlModule::Lock call without CAtlModule::Unlock pair.
|
|
|
|
|
Thanks for the help. I don't want to make my com dll a service right now. I tried to return S_FALSE in DllCanUnloadNow and also called CAtlModule::Lock without calling Unlock. Doesn't seem to work.
I remember when building a com dll in VB6, you can specify a project setting called "retained in memory" which will do exactly what I want. Is there an equivalent of this feature in VC++?
|
|
|
|
|
Returning S_FALSE from DllCanUnloadNow should leave the dll loaded. I don't know VB, so I cannot tell exactly what that property does, but I suppose it will do the same thing ( return false from can unload now). Did you check if it's the same process ? ( maybe the process will exit, so normally all the dlls will be unloaded).
|
|
|
|