I) Global Explanation
Hello,
I'm developing an app in C# using Microsoft.Office.Interop.Excel. In my case I implement some olds macros stored in a file to an Excel Workbook, opened by C#, to upgrade them without re-coding macros in my app.
Globally there is my process in my app :
- The user select an updated macro,
- I check if the macro require something :
- Here I set the register Key CURRENT_USER\SOFTWARE\Microsoft\Office\[office_ID].0\Excel\Security\AccessVBOM to 1 for allows macro/VBProject modifications
- I instantiate an Excel app with a new workbook
- I set optimization Excel execution parameters (disable refresh... that kind of stuff)
- I add my macro, stored in a file, to the workbook
- I execute the macro through Excel
- I remove the macro from the Excel
- I unset optimizations Excel executions parameters
- I reset registers keys (.../AccessVBOM = 0)
II) My problem and my research result
In the "I add my macro, stored in a file, to the workbook" part, when I used the following instruction to add a VBProject to the workbook (required to add the macro) I get an error 800A03EC.
/// wb is a workbook object
VBComponent module = wb.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);
This error is send with a message (grossly traduce) : "The access to VB Project are not trust."
As I see on the Internet, this error occurs when an option in Excel isn't correctly set. This option can by handle with the CURRENT_USER\SOFTWARE\Microsoft\Office\[office_ID].0\Excel\Security\AccessVBOM register key. And I'm building my app with a register key management for avoid this problem.
And as you will see on the debug display part, we can see the option is correctly set on the execution.
My question : there is another case when this error occurs?
III) Debug analyse
When I catch the ComException, I use the following to display registers keys values.
/// RequirementManager is my own class, use to set and unset endpoints computers parameters, before and after each user action
RegistryKey reg;
for (int i = RequirementManager.EXCEL_ID_HANDLED_MIN; i < RequirementManager.EXCEL_ID_HANDLED_MAX; i++)
{
reg = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Microsoft\Office\" + i + @".0\Excel\Security\", RegistryKeyPermissionCheck.ReadSubTree);
Debug.WriteLine(String.Format(@"Value of CURRENT_USER\SOFTWARE\Microsoft\Office\{0}.0\Excel\Security\AccessVBOM = {1}", i, reg.GetValue("AccessVBOM")), "Debug");
reg.Close();
}
reg = null;
And here is the console output of this lines :
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\11.0\Excel\Security\AccessVBOM = 1
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Excel\Security\AccessVBOM = 1
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\13.0\Excel\Security\AccessVBOM = 1
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Excel\Security\AccessVBOM = 1
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Excel\Security\AccessVBOM = 1
Debug: Value of CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Excel\Security\AccessVBOM = 1
As you can see, the option is correctly set when the error occurs. And all instance of Excel are closed before the modification of register keys, for avoid problem. I use similar algorithm to modify this range of register keys, like a lazy boy.
Any idea are welcome
Regards, Dykoine
IV) Answer Reaction
@prizm1 This parameter if macro are allowed or not (display orange warning message), and on my computer (while test) I set it to allow all macro.
After test, I can see this option doesn't protect the user, because we can open an Excel file with C# and execute a macro in it without be block by this option even if you use "disabled all without notification".