H
Henrik
Hello,
I have a question about DSOFile, which is used for writing custom properties
to for example Office-files.
It can be downloaded from her
(http://www.microsoft.com/downloads/...C6-520B-4A0A-878A-53EC8300C4C2&displaylang=en).
We have been using this component for many years in both x86 and x64
environments without any problems.
The previous version, 2.0, was working well in both x86 and x64 environment,
however it only supported OLE-files (not the new Office 2007 format).
The new version, 2.1, supporting Office 2007 new file format as long as a
handler is installed, has some problems. Just like the previous version, it
is working well in both x86 and x64 environment for OLE-files (old Office
file format). But for new OOXML (Office 2007) file format it does not work in
a x64 environment, however x86 works fine also for OOXML files.
The error returned is (note that the very same file on a x86 environment
will work):
************** Exception Text **************
System.Runtime.InteropServices.COMException (0x80041104): The document is
not an OLE file, and does not support extended document properties.
at DSOFile.OleDocumentPropertiesClass.Open(String sFileName, Boolean
ReadOnly, dsoFileOpenOptions Options)
at FilePropDemoVB7.FilePropDempenDocumentProperties() in
D:\CDBackup\Projects\dsofile\2.1\Samples\VB7\FilePropDemo.vb:line 524
at FilePropDemoVB7.FilePropDemo.cmdOpen_Click(Object sender, EventArgs e)
in D:\CDBackup\Projects\dsofile\2.1\Samples\VB7\FilePropDemo.vb:line 724
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
If we look into the DSOFile sourcefile docprop.cpp from Microsoft, that also
is distributed in the above download, the following lines are the ones that
most likely returnes our error:
if (StgIsStorageFile(m_bstrFileName) == S_OK)
{
// Get the data from IStorage...
hr = StgOpenStorage(m_bstrFileName, NULL, dwOpenMode, NULL, 0,
&m_pStorage);
// If we failed to gain write access, try to just read access if caller
allows
// it. This function will open the OLE file in transacted read mode, which
// covers cases where the file is in use or is on a read-only share. We
can't
// save after the open so we force the read-only flag on...
if (((hr == STG_E_ACCESSDENIED) || (hr == STG_E_SHAREVIOLATION)) &&
(m_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess))
{
m_fReadOnly = TRUE;
hr = StgOpenStorage(m_bstrFileName, NULL,
(STGM_READ | STGM_TRANSACTED | STGM_SHARE_DENY_NONE), NULL, 0,
&m_pStorage);
}
// If we are lucky, we have a storage to read from, so ask OLE to open the
// associated property set for the file and return the IPSS iface...
if (SUCCEEDED(hr))
{
hr = m_pStorage->QueryInterface(IID_IPropertySetStorage,
(void**)&m_pPropSetStg);
}
}
else if ((m_dwFlags & dsoOptionOnlyOpenOLEFiles) !=
dsoOptionOnlyOpenOLEFiles)
{
// If caller would like non-OLE property sets, we can try to provide them.
There
// are two types: (1) explicit metadata handlers registered by file type;
or (2)
// NTFS 5.0+ property stream data in NTFS file header (which is actually
saved as
// alternate stream). The former is custom provider to save data inside
the file
// without using OLE. The later is available for any file on NTFS5 disk.
CLSID clsidMetaHandler = {0};
IPersistFile *prtsf = NULL;
if (DsoGetMetaHandler(m_bstrFileName, &clsidMetaHandler) == S_OK)
{
// Create instance of the Metadata Handler object...
hr = CoCreateInstance(clsidMetaHandler, NULL, CLSCTX_INPROC,
IID_IPersistFile, (void**)&prtsf);
if (SUCCEEDED(hr))
{
// Ask it to load the file for parsing...
hr = prtsf->Load(m_bstrFileName, dwOpenMode);
if (SUCCEEDED(hr))
{
// If it succeeded, ask for the property set storage...
hr = prtsf->QueryInterface(IID_IPropertySetStorage,
(void**)&m_pPropSetStg);
if (SUCCEEDED(hr)){ASSIGN_INTERFACE(m_pPrstFile, prtsf);}
}
prtsf->Release();
}
else hr = DSO_E_NODOCUMENTPROPS; // bad news, unable to load handler.
}
else if (v_pfnStgOpenStorageEx)
{
// On Win2K+ we can try and open plain files on NTFS 5.0 drive and get
// the NTFS version of OLE properties (saved in alt stream)...
hr = (v_pfnStgOpenStorageEx)(m_bstrFileName, dwOpenMode, STGFMT_FILE, 0,
NULL, 0,
IID_IPropertySetStorage, (void**)&m_pPropSetStg);
// If we failed to gain write access, try to just read access if caller
// wants us to. This only works for access block, not share violations...
if ((hr == STG_E_ACCESSDENIED) && (!m_fReadOnly) &&
(m_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess))
{
m_fReadOnly = TRUE;
hr = (v_pfnStgOpenStorageEx)(m_bstrFileName, (STGM_READ |
STGM_SHARE_EXCLUSIVE), STGFMT_FILE,
0, NULL, 0, IID_IPropertySetStorage, (void**)&m_pPropSetStg);
}
}
else
{ // If we land here, the file is not OLE and not on NTFS5 drive...
hr = DSO_E_NODOCUMENTPROPS;
}
}
else
{ // If we land here, the file is not OLE and caller asked for OLE
only...
hr = DSO_E_NODOCUMENTPROPS;
}
Every occurance of "DSO_E_NODOCUMENTPROPS" is possible candidate to where
our exception occurs. We feel that "// bad news, unable to load handler." may
be the most likely location, but it is only a guess.
Is there anyone that knows if there is any issue with DSOFile 2.1 on x64
systems when working with OOXML-files (even though OLE-files works?).
We are running:
- Windows 2003 Server x64.
- Office 2007 full install with SP1 (have tried without SP1 also).
- The test application that is provided in the above download link from
Microsoft (even though we have our own application, the very same error that
we get in our app can be reproduced by the default sample app
"FilePropDemoVB7" installed together with DSOFile).
Please let me know if you have any input on this or need any more info... We
are not sure if x86/x64 is the actual problem, it is only a guess from us. It
may be another problem, but if anyone successfully used DSOFile for OOXML
files on x64, then we can rule that out.
Thank you very much for your help!!
I have a question about DSOFile, which is used for writing custom properties
to for example Office-files.
It can be downloaded from her
(http://www.microsoft.com/downloads/...C6-520B-4A0A-878A-53EC8300C4C2&displaylang=en).
We have been using this component for many years in both x86 and x64
environments without any problems.
The previous version, 2.0, was working well in both x86 and x64 environment,
however it only supported OLE-files (not the new Office 2007 format).
The new version, 2.1, supporting Office 2007 new file format as long as a
handler is installed, has some problems. Just like the previous version, it
is working well in both x86 and x64 environment for OLE-files (old Office
file format). But for new OOXML (Office 2007) file format it does not work in
a x64 environment, however x86 works fine also for OOXML files.
The error returned is (note that the very same file on a x86 environment
will work):
************** Exception Text **************
System.Runtime.InteropServices.COMException (0x80041104): The document is
not an OLE file, and does not support extended document properties.
at DSOFile.OleDocumentPropertiesClass.Open(String sFileName, Boolean
ReadOnly, dsoFileOpenOptions Options)
at FilePropDemoVB7.FilePropDempenDocumentProperties() in
D:\CDBackup\Projects\dsofile\2.1\Samples\VB7\FilePropDemo.vb:line 524
at FilePropDemoVB7.FilePropDemo.cmdOpen_Click(Object sender, EventArgs e)
in D:\CDBackup\Projects\dsofile\2.1\Samples\VB7\FilePropDemo.vb:line 724
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
If we look into the DSOFile sourcefile docprop.cpp from Microsoft, that also
is distributed in the above download, the following lines are the ones that
most likely returnes our error:
if (StgIsStorageFile(m_bstrFileName) == S_OK)
{
// Get the data from IStorage...
hr = StgOpenStorage(m_bstrFileName, NULL, dwOpenMode, NULL, 0,
&m_pStorage);
// If we failed to gain write access, try to just read access if caller
allows
// it. This function will open the OLE file in transacted read mode, which
// covers cases where the file is in use or is on a read-only share. We
can't
// save after the open so we force the read-only flag on...
if (((hr == STG_E_ACCESSDENIED) || (hr == STG_E_SHAREVIOLATION)) &&
(m_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess))
{
m_fReadOnly = TRUE;
hr = StgOpenStorage(m_bstrFileName, NULL,
(STGM_READ | STGM_TRANSACTED | STGM_SHARE_DENY_NONE), NULL, 0,
&m_pStorage);
}
// If we are lucky, we have a storage to read from, so ask OLE to open the
// associated property set for the file and return the IPSS iface...
if (SUCCEEDED(hr))
{
hr = m_pStorage->QueryInterface(IID_IPropertySetStorage,
(void**)&m_pPropSetStg);
}
}
else if ((m_dwFlags & dsoOptionOnlyOpenOLEFiles) !=
dsoOptionOnlyOpenOLEFiles)
{
// If caller would like non-OLE property sets, we can try to provide them.
There
// are two types: (1) explicit metadata handlers registered by file type;
or (2)
// NTFS 5.0+ property stream data in NTFS file header (which is actually
saved as
// alternate stream). The former is custom provider to save data inside
the file
// without using OLE. The later is available for any file on NTFS5 disk.
CLSID clsidMetaHandler = {0};
IPersistFile *prtsf = NULL;
if (DsoGetMetaHandler(m_bstrFileName, &clsidMetaHandler) == S_OK)
{
// Create instance of the Metadata Handler object...
hr = CoCreateInstance(clsidMetaHandler, NULL, CLSCTX_INPROC,
IID_IPersistFile, (void**)&prtsf);
if (SUCCEEDED(hr))
{
// Ask it to load the file for parsing...
hr = prtsf->Load(m_bstrFileName, dwOpenMode);
if (SUCCEEDED(hr))
{
// If it succeeded, ask for the property set storage...
hr = prtsf->QueryInterface(IID_IPropertySetStorage,
(void**)&m_pPropSetStg);
if (SUCCEEDED(hr)){ASSIGN_INTERFACE(m_pPrstFile, prtsf);}
}
prtsf->Release();
}
else hr = DSO_E_NODOCUMENTPROPS; // bad news, unable to load handler.
}
else if (v_pfnStgOpenStorageEx)
{
// On Win2K+ we can try and open plain files on NTFS 5.0 drive and get
// the NTFS version of OLE properties (saved in alt stream)...
hr = (v_pfnStgOpenStorageEx)(m_bstrFileName, dwOpenMode, STGFMT_FILE, 0,
NULL, 0,
IID_IPropertySetStorage, (void**)&m_pPropSetStg);
// If we failed to gain write access, try to just read access if caller
// wants us to. This only works for access block, not share violations...
if ((hr == STG_E_ACCESSDENIED) && (!m_fReadOnly) &&
(m_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess))
{
m_fReadOnly = TRUE;
hr = (v_pfnStgOpenStorageEx)(m_bstrFileName, (STGM_READ |
STGM_SHARE_EXCLUSIVE), STGFMT_FILE,
0, NULL, 0, IID_IPropertySetStorage, (void**)&m_pPropSetStg);
}
}
else
{ // If we land here, the file is not OLE and not on NTFS5 drive...
hr = DSO_E_NODOCUMENTPROPS;
}
}
else
{ // If we land here, the file is not OLE and caller asked for OLE
only...
hr = DSO_E_NODOCUMENTPROPS;
}
Every occurance of "DSO_E_NODOCUMENTPROPS" is possible candidate to where
our exception occurs. We feel that "// bad news, unable to load handler." may
be the most likely location, but it is only a guess.
Is there anyone that knows if there is any issue with DSOFile 2.1 on x64
systems when working with OOXML-files (even though OLE-files works?).
We are running:
- Windows 2003 Server x64.
- Office 2007 full install with SP1 (have tried without SP1 also).
- The test application that is provided in the above download link from
Microsoft (even though we have our own application, the very same error that
we get in our app can be reproduced by the default sample app
"FilePropDemoVB7" installed together with DSOFile).
Please let me know if you have any input on this or need any more info... We
are not sure if x86/x64 is the actual problem, it is only a guess from us. It
may be another problem, but if anyone successfully used DSOFile for OOXML
files on x64, then we can rule that out.
Thank you very much for your help!!