Excel Add-ins (*.xla) do not support embedding and cannot
be opened inside of Internet Explorer. End users do not normally open XLAs;
instead they open an XLS that (if needed) loads one or more XLAs during
startup. Only in rare cases does a user need to start an XLA directly. In these
situations, scripting code can be used if the file is to be started through
Internet Explorer.
Automation of Excel from script does not work,
however, if the client computer has been set to High security or if the
"Initialize and script ActiveX controls not marked safe for scripting" option
has been set to Disable. These clients must lower their security to "Prompt" to
be able to choose to run the script code and open the XLA. XLAs and Excel
Automation are not safe for scripting by default.
For more information about how to
programmatically change these Internet Explorer options from a trusted control
or setup utility (but not script), click the following article number to view the article in the Microsoft Knowledge Base:
182569
Internet Explorer security zones registry entries for advanced users
Other Workarounds and Considerations
If scripting is not a solution that fits your Web design, you can
seek to avoid the problem through registry changes and modification of the XLA
file itself. This must be done outside of Internet Explorer or Active Server
Pages (ASP), and is not a viable solution for Web applications where the client
environment cannot be controlled. The following discussion explains in more
detail the cause of the problem and what you must do to avoid the problem.
Because Internet Explorer uses the MIME type specified by the server
during an HTTP GET operation, you need to prevent IIS (or the Web server with
which you are communicating) from associating the *.xla extension with the
"application/vnd.ms-excel" MIME type. IIS saves this information in the
property settings for the Web folder (that is, in the metabase). To change the
behavior of your IIS Web site, you need to edit the metabase. To do this for
IIS versions 4.0 and 5.0, you can use the following steps:
- Start the Internet Information Services Manager.
- Right-click the folder containing the add-in under the Default Web Site, and choose Properties from the drop-down menu.
- Select the HTTP Headers tab, and click File Types under the MIME Map section.
- Click New Type. Specify .xla for the Associated Extension, and text/plain for the Content Type (MIME). Click OK to add the file type.
- Click OK to close the File Types dialog box, and then click OK to close the Folder Properties dialog box.
NOTE: The IIS server may need to be shut down and restarted for the
changes to take effect.
For files opened locally, or for files opened from a Web server
that did not specify a MIME type, Internet Explorer uses the CLSID from the
file itself to associate a server and load the file. Because an XLA is the same
an XLS, the CLSID for the root storage is to an Excel Workbook (Excel.Sheet.8).
In order to prevent Internet Explorer from using this CLSID, you need to strip
it from the file using OLE Structured Storage APIs. This should not affect the
functionality of the file in Excel, but if the file is modified in Excel, the
CLSID is re-inserted into the file.
The following Microsoft Visual
C++ code shows you how to replace the CLSID of the main storage with a NULL
CLSID:
#include <windows.h>
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR pszCmdLine, int nCmdShow)
{
WCHAR wszFile[MAX_PATH];
CHAR szFile[MAX_PATH];
szFile[0] = 0;
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
if (FAILED(CoInitialize(NULL)))
return -1;
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "Microsoft Excel Addins (*.xla)\0*.xla\0\0";
ofn.nFilterIndex = 1L;
ofn.lpstrDefExt = "xla";
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn) && (szFile[0] != '\0'))
{
if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
szFile, -1, wszFile, MAX_PATH))
{
MessageBox(NULL, "Can't convert to Unicode!",
"XlaClsid", MB_ICONSTOP | MB_SETFOREGROUND);
return -2;
}
IStorage* pstg = NULL;
HRESULT hr = StgOpenStorage(wszFile, NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &pstg);
if (SUCCEEDED(hr) && pstg)
{
pstg->SetClass(GUID_NULL);
pstg->Release();
MessageBox(NULL, "Call succeeded. CLSID has been stripped.",
"XlaClsid", MB_ICONINFORMATION | MB_SETFOREGROUND);
}
else
{
MessageBox(NULL, "Unable to open file. It may be in use.",
"XlaClsid", MB_ICONSTOP | MB_SETFOREGROUND);
}
}
CoUninitialize();
return 0;
}
Note Internet Explorer does not check the CLSID from the structured
storage file if the XLA is opened from the Address bar, but does check if the
XLA is referenced in a hyperlink. While this behavior may change in future
versions of Internet Explorer, you should not rely on the current behavior and
forgo removing the CLSID from the XLA.
If the file's CLSID has been
removed, and the server has not specified a MIME type, Internet Explorer then
uses the file extension to start Excel and load the XLA. Depending on the
configuration of the registry on the client system, the file may still open for
embedding, so modification of the client registry may be needed. The registry
keys of interest are:
����-and-
HKEY_CLASSES_ROOT\Excel.Addin
You need to make sure that there is no "Content Type" value
specified under these registry keys because the keys can re-direct Internet
Explorer to a MIME type, and from there back to the workbook CLSID. Also, the
Excel.Addin key may contain a CLSID subkey that also re-directs Internet
Explorer to use embedding. This key should be renamed or removed to prevent
Internet Explorer from finding the CLSID.
If all of the preceding
steps are followed, Internet Explorer will be unable to locate a CLSID for the
file type and will load the file with a
ShellExecute command. This runs the file as if the user had double-clicked it
from Internet Explorer.