DotNetNewsgroup.com  
web access to complete list of Microsoft.NET newsgroups
   home   |   control panel login   |   archive  |  
 
  carried group
academic
adonet
aspnet
aspnet.announcements
aspnet.buildingcontrols
aspnet.caching
aspnet.datagridcontrol
aspnet.mobile
aspnet.security
aspnet.webcontrols
aspnet.webservices
assignment_manager
datatools
dotnet.distributed_apps
dotnet.general
dotnet.myservices
dotnet.nternationalization
dotnet.scripting
dotnet.security
dotnet.vjsharp
dotnet.vsa
dotnet.xml
dotnetfaqs
framework
framework.clr
framework.compactframework
framework.component_services
framework.controls
framework.databinding
framework.drawing
framework.enhancements
framework.interop
framework.odbcnet
framework.performance
framework.remoting
framework.sdk
framework.setup
framework.webservices
framework.windowsforms
framework.wmi
frwk.windowsforms.designtime
lang.csharp
lang.jscript
lang.vb
lang.vb.controls
lang.vb.data
lang.vb.upgrade
lang.vc
lang.vc.libraries
  
 
start date: Mon, 9 Jul 2007 10:12:07 -0700,    posted on: microsoft.public.dotnet.framework.interop        back       

Thread Index
  1    Heath Kelly
          2    Michael Phillips, Jr. 0.c0m
                 3    Heath Kelly
                        4    Heath Kelly
          5    Michael Phillips, Jr. 0.c0m
          6    Heath Kelly
          7    Michael Phillips, Jr. 0.c0m


Marshal.QueryInterface returning E_NOINTERFACE   
I use the ReadClassStg API call to find out what application owns a given 
storage.  In my test case it is Word.

//4) Determine the CLSID of the COM object that owns the IStorage.
Guid clsid = new Guid();
ReadClassStg(storage, ref clsid);

I then create a instance of Word as follows:

//5) Use the CLSID to instantiate the COM object using interop.
Type type = Type.GetTypeFromCLSID(clsid);
Object comObj = Activator.CreateInstance(type);

This works fine and I can see that an instance of Word is loaded into my 
object.

//6 Return a pointer to the objects IUnknown interface.
IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
IntPtr p;
Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);

Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE?  p 
is always 0.  Not sure what I am doing wrong.  Can anyone help?

Heath.
Date:Mon, 9 Jul 2007 10:12:07 -0700   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   

> Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);

> Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> p
> is always 0.  Not sure what I am doing wrong.  Can anyone help?


You need to request an interface that is exposed by this COM object.

For example, you may request an IStream interface, an IDataObject, etc. 
"ref clsid" is not a valid IID of an Interface.

"Heath Kelly"  wrote in message 
news:F8F297C0-950C-4D63-8254-5C3C6D84F4C7@microsoft.com...

>I use the ReadClassStg API call to find out what application owns a given
> storage.  In my test case it is Word.
>
> //4) Determine the CLSID of the COM object that owns the IStorage.
> Guid clsid = new Guid();
> ReadClassStg(storage, ref clsid);
>
> I then create a instance of Word as follows:
>
> //5) Use the CLSID to instantiate the COM object using interop.
> Type type = Type.GetTypeFromCLSID(clsid);
> Object comObj = Activator.CreateInstance(type);
>
> This works fine and I can see that an instance of Word is loaded into my
> object.
>
> //6 Return a pointer to the objects IUnknown interface.
> IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
> IntPtr p;
> Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);
>
> Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> p
> is always 0.  Not sure what I am doing wrong.  Can anyone help?
>
> Heath. 
Date:Wed, 11 Jul 2007 19:26:12 -0400   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   
Thanks Michael your advice has taken me a step closer to my goal.   However, 
I'm still not sure if I am doing this correctly.  I can now load the COM 
object from the storage but when it comes to saving it out to file I get an 
E_FAIL.

//6) Get a pointer to the IPersistStorage Interface.
Guid IID_IPersistStorage = typeof(IPersistStorage).GUID;
IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
IntPtr ptrStorage;
Int32 r = Marshal.QueryInterface(pIUnk, ref IID_IPersistStorage, out 
ptrStorage);
//r = S_OK

//7) Load the COM object from the storage.
IPersistStorage per = 
(IPersistStorage)Marshal.GetObjectForIUnknown(ptrStorage);
r = per.Load(Marshal.GetIUnknownForObject(storage));
//r = S_OK
 
//8) Get a pointer to the IPersistFile Interface.
Guid IID_IPersistFile = typeof(IPersistFile).GUID;
IntPtr ptrFile;
r = Marshal.QueryInterface(pIUnk, ref IID_IPersistFile, out ptrFile);
//r = S_OK

 //9) Save the file to disk.
IPersistFile perFile = (IPersistFile)Marshal.GetObjectForIUnknown(ptrFile);
r = perFile.Save(@"D:\Data\Result\Output.doc", true);
//r = E_FAIL

Any further advice?

Regards,
Heath

"Michael Phillips, Jr." wrote:


> > Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);
> 
> > Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> > p
> > is always 0.  Not sure what I am doing wrong.  Can anyone help?
> 
> You need to request an interface that is exposed by this COM object.
> 
> For example, you may request an IStream interface, an IDataObject, etc. 
> "ref clsid" is not a valid IID of an Interface.
> 
> "Heath Kelly"  wrote in message 
> news:F8F297C0-950C-4D63-8254-5C3C6D84F4C7@microsoft.com...
> >I use the ReadClassStg API call to find out what application owns a given
> > storage.  In my test case it is Word.
> >
> > //4) Determine the CLSID of the COM object that owns the IStorage.
> > Guid clsid = new Guid();
> > ReadClassStg(storage, ref clsid);
> >
> > I then create a instance of Word as follows:
> >
> > //5) Use the CLSID to instantiate the COM object using interop.
> > Type type = Type.GetTypeFromCLSID(clsid);
> > Object comObj = Activator.CreateInstance(type);
> >
> > This works fine and I can see that an instance of Word is loaded into my
> > object.
> >
> > //6 Return a pointer to the objects IUnknown interface.
> > IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
> > IntPtr p;
> > Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);
> >
> > Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> > p
> > is always 0.  Not sure what I am doing wrong.  Can anyone help?
> >
> > Heath. 
> 
> 
> 
Date:Thu, 12 Jul 2007 04:30:01 -0700   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   
I've since realised that Office documents are saving correctly and that it is 
only certain other file types held within the Storage that don't save 
properly.  Probably something to do with their host application.  Will look 
into it further.

"Heath Kelly" wrote:


> Thanks Michael your advice has taken me a step closer to my goal.   However, 
> I'm still not sure if I am doing this correctly.  I can now load the COM 
> object from the storage but when it comes to saving it out to file I get an 
> E_FAIL.
> 
> //6) Get a pointer to the IPersistStorage Interface.
> Guid IID_IPersistStorage = typeof(IPersistStorage).GUID;
> IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
> IntPtr ptrStorage;
> Int32 r = Marshal.QueryInterface(pIUnk, ref IID_IPersistStorage, out 
> ptrStorage);
> //r = S_OK
> 
> //7) Load the COM object from the storage.
> IPersistStorage per = 
> (IPersistStorage)Marshal.GetObjectForIUnknown(ptrStorage);
> r = per.Load(Marshal.GetIUnknownForObject(storage));
> //r = S_OK
>  
> //8) Get a pointer to the IPersistFile Interface.
> Guid IID_IPersistFile = typeof(IPersistFile).GUID;
> IntPtr ptrFile;
> r = Marshal.QueryInterface(pIUnk, ref IID_IPersistFile, out ptrFile);
> //r = S_OK
> 
>  //9) Save the file to disk.
> IPersistFile perFile = (IPersistFile)Marshal.GetObjectForIUnknown(ptrFile);
> r = perFile.Save(@"D:\Data\Result\Output.doc", true);
> //r = E_FAIL
> 
> Any further advice?
> 
> Regards,
> Heath
> 
> "Michael Phillips, Jr." wrote:
> 
> > > Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);
> > 
> > > Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> > > p
> > > is always 0.  Not sure what I am doing wrong.  Can anyone help?
> > 
> > You need to request an interface that is exposed by this COM object.
> > 
> > For example, you may request an IStream interface, an IDataObject, etc. 
> > "ref clsid" is not a valid IID of an Interface.
> > 
> > "Heath Kelly"  wrote in message 
> > news:F8F297C0-950C-4D63-8254-5C3C6D84F4C7@microsoft.com...
> > >I use the ReadClassStg API call to find out what application owns a given
> > > storage.  In my test case it is Word.
> > >
> > > //4) Determine the CLSID of the COM object that owns the IStorage.
> > > Guid clsid = new Guid();
> > > ReadClassStg(storage, ref clsid);
> > >
> > > I then create a instance of Word as follows:
> > >
> > > //5) Use the CLSID to instantiate the COM object using interop.
> > > Type type = Type.GetTypeFromCLSID(clsid);
> > > Object comObj = Activator.CreateInstance(type);
> > >
> > > This works fine and I can see that an instance of Word is loaded into my
> > > object.
> > >
> > > //6 Return a pointer to the objects IUnknown interface.
> > > IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
> > > IntPtr p;
> > > Int32 result = Marshal.QueryInterface(pIUnk, ref clsid, out p);
> > >
> > > Why is Marshal.QueryInterface always returning the hresult E_NOINTERFACE? 
> > > p
> > > is always 0.  Not sure what I am doing wrong.  Can anyone help?
> > >
> > > Heath. 
> > 
> > 
> > 
Date:Thu, 12 Jul 2007 06:22:04 -0700   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   
It is not clear to me what your goal is.

A compound document file is laid out as a file system with directories as 
storage objects and files as streams.

The storage objects are not real directories.  They represent individual com 
storage objects.
The files are not real files they are data represented as a stream.


> //9) Save the file to disk.
> IPersistFile perFile = 
> (IPersistFile)Marshal.GetObjectForIUnknown(ptrFile);
> r = perFile.Save(@"D:\Data\Result\Output.doc", true);
> //r = E_FAIL


What are you trying to save?

If for example, there was an embedded object such an excel spreadsheet.
You would instantiate the excel object and load its storage via the 
IPersistStorage interface.

You would then create a new compound document via StgCreateDocfile and then 
use OleSave to save the excel storage
object and all of its associated streams.

The clsid of the com object is written to the storage object.  It is that 
clsid that you use to instantiate the com object.

Each embedded object in your Word document has a different format.  Some 
objects are packaged like embedded pdf files.
For pdf files the above will not work.  You would have to extract the 
"Contents" stream and use the windows file system api
to write the file.
Date:Thu, 12 Jul 2007 09:34:39 -0400   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   
Michael, my goal is to extract all documents embedded within any given 
compound document.  Here is the current revision of my code:

//6) Get a pointer to the IPersistStorage Interface.
//comObj = Word, Excel, etc.
Guid IID_IPersistStorage = typeof(IPersistStorage).GUID;
IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
IntPtr ptrStorage;
Int32 r = Marshal.QueryInterface(pIUnk, ref IID_IPersistStorage, out 
ptrStorage);

//7) Load the COM object from the storage.
IPersistStorage per = 
(IPersistStorage)Marshal.GetObjectForIUnknown(ptrStorage);
r = per.Load(Marshal.GetIUnknownForObject(store));

//8) Create new storage and save to disk.
IStorage temp;
StgCreateDocfile(@"D:\Data\Result\Output" + count,    
STGM.READWRITE|STGM.SHARE_EXCLUSIVE|STGM.CREATE, 0, out temp);
OleSave(per, temp, false);

I understand that this approach will not work for all documents.  For 
non-office documents I have a different approach where I where I write the 
"CONTENTS" stream to the file system.  This works for PDFs for example.

The above approach works perfectly for all office document types except 
Excel.  Excel documents are created, however they seem to be lacking some 
information and will not open natively.  I can "fix" them by dragging them 
into IE, where they can be viewed, and then saving them.  This work around is 
not acceptable to me.  

Excel storages are associated with the clsid of Excel.Application.  However, 
I can't get an IPersistStorage interface for this object, instead I need to 
use the clsid of Excel.Sheet to get any joy here at all.  Wondering if my 
problem is somehow related.

Regards,
Heath.


"Michael Phillips, Jr." wrote:


> It is not clear to me what your goal is.
> 
> A compound document file is laid out as a file system with directories as 
> storage objects and files as streams.
> 
> The storage objects are not real directories.  They represent individual com 
> storage objects.
> The files are not real files they are data represented as a stream.
> 
> > //9) Save the file to disk.
> > IPersistFile perFile = 
> > (IPersistFile)Marshal.GetObjectForIUnknown(ptrFile);
> > r = perFile.Save(@"D:\Data\Result\Output.doc", true);
> > //r = E_FAIL
> 
> What are you trying to save?
> 
> If for example, there was an embedded object such an excel spreadsheet.
> You would instantiate the excel object and load its storage via the 
> IPersistStorage interface.
> 
> You would then create a new compound document via StgCreateDocfile and then 
> use OleSave to save the excel storage
> object and all of its associated streams.
> 
> The clsid of the com object is written to the storage object.  It is that 
> clsid that you use to instantiate the com object.
> 
> Each embedded object in your Word document has a different format.  Some 
> objects are packaged like embedded pdf files.
> For pdf files the above will not work.  You would have to extract the 
> "Contents" stream and use the windows file system api
> to write the file. 
> 
> 
> 
Date:Mon, 16 Jul 2007 10:06:03 -0700   Author:  

Re: Marshal.QueryInterface returning E_NOINTERFACE   

> The above approach works perfectly for all office document types except
> Excel.  Excel documents are created, however they seem to be lacking some
> information and will not open natively.  I can "fix" them by dragging them
> into IE, where they can be viewed, and then saving them.  This work around 
> is
> not acceptable to me.


It works for excel also.  However the excel spreadsheet is marked as hidden.

There are two ways to solve the problem.

1) Use OLE Automation to create an "Excel.Application" ole object and get 
the global Windows collection and mark the hidden window as "visible".
    This approach is not very fast as the Excel application must be present 
on the system and it takes somes time to load.  Using IDispatch is 
cumbersome.
2) Use the IStream to find the "WINDOW1" record in the "Workbook" stream. 
The record is defined as 0x003D.  Once found you load the record.
    The record has an options bit field.
    Here is the structure:
    typedef struct _WINDOW1_RECORD
    {
           //short window1Marker;  // Should be 0x003D
           //short recordSize;   // size of record in bytes, 
biff2-biff4(8bytes),biff5-biff8(18bytes)
           short hpos;
           short vpos;
           short height;
           short width;
           short options;  // bit 1, 0 - visible, 1 - hidden
           short idxActiveWkSheet;
           short idxVisibleTab;
           short selectedWkSheet;
           short widthTabBar;
    } WINDOW1_RECORD;
    It is a "short".  If you set it to 0,  and then save the stream, the 
excel spreadsheet will be visible.




"Heath Kelly"  wrote in message 
news:E9DDF098-DCB2-4541-B780-387910949720@microsoft.com...

> Michael, my goal is to extract all documents embedded within any given
> compound document.  Here is the current revision of my code:
>
> //6) Get a pointer to the IPersistStorage Interface.
> //comObj = Word, Excel, etc.
> Guid IID_IPersistStorage = typeof(IPersistStorage).GUID;
> IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
> IntPtr ptrStorage;
> Int32 r = Marshal.QueryInterface(pIUnk, ref IID_IPersistStorage, out
> ptrStorage);
>
> //7) Load the COM object from the storage.
> IPersistStorage per =
> (IPersistStorage)Marshal.GetObjectForIUnknown(ptrStorage);
> r = per.Load(Marshal.GetIUnknownForObject(store));
>
> //8) Create new storage and save to disk.
> IStorage temp;
> StgCreateDocfile(@"D:\Data\Result\Output" + count,
> STGM.READWRITE|STGM.SHARE_EXCLUSIVE|STGM.CREATE, 0, out temp);
> OleSave(per, temp, false);
>
> I understand that this approach will not work for all documents.  For
> non-office documents I have a different approach where I where I write the
> "CONTENTS" stream to the file system.  This works for PDFs for example.
>
> The above approach works perfectly for all office document types except
> Excel.  Excel documents are created, however they seem to be lacking some
> information and will not open natively.  I can "fix" them by dragging them
> into IE, where they can be viewed, and then saving them.  This work around 
> is
> not acceptable to me.
>
> Excel storages are associated with the clsid of Excel.Application. 
> However,
> I can't get an IPersistStorage interface for this object, instead I need 
> to
> use the clsid of Excel.Sheet to get any joy here at all.  Wondering if my
> problem is somehow related.
>
> Regards,
> Heath.
>
>
> "Michael Phillips, Jr." wrote:
>
>> It is not clear to me what your goal is.
>>
>> A compound document file is laid out as a file system with directories as
>> storage objects and files as streams.
>>
>> The storage objects are not real directories.  They represent individual 
>> com
>> storage objects.
>> The files are not real files they are data represented as a stream.
>>
>> > //9) Save the file to disk.
>> > IPersistFile perFile =
>> > (IPersistFile)Marshal.GetObjectForIUnknown(ptrFile);
>> > r = perFile.Save(@"D:\Data\Result\Output.doc", true);
>> > //r = E_FAIL
>>
>> What are you trying to save?
>>
>> If for example, there was an embedded object such an excel spreadsheet.
>> You would instantiate the excel object and load its storage via the
>> IPersistStorage interface.
>>
>> You would then create a new compound document via StgCreateDocfile and 
>> then
>> use OleSave to save the excel storage
>> object and all of its associated streams.
>>
>> The clsid of the com object is written to the storage object.  It is that
>> clsid that you use to instantiate the com object.
>>
>> Each embedded object in your Word document has a different format.  Some
>> objects are packaged like embedded pdf files.
>> For pdf files the above will not work.  You would have to extract the
>> "Contents" stream and use the windows file system api
>> to write the file.
>>
>>
>> 
Date:Mon, 16 Jul 2007 20:13:44 -0400   Author:  

Google
 
Web dotnetnewsgroup.com


COPYRIGHT ?2005, EUROFRONT WORLDWIDE LTD., ALL RIGHT RESERVE  |   Contact us