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".
Here the code which haven't made any problems with putting VBA into an Excel file. Maybe you need to save it to disk first before entering the Code, since the Project is determined by the filename. Just an addition, and no real solution: