title: Programmatic Execution Excel Macro on Remote Machine from a website
body: <p>I have a website where users generate an Excel report using a macro, when I try to run it in my local machine it generates perfectly and runs the macro inside Excel.  When I publish it into the server and at the same time I am logged in there (RDP open session) and try to run it from a browser outside that server it is also running as expected.  The problem occurs when I am logged off in the server (RDP) then run it in a browser outside the server (ie from my machine) the macro does not run but creates my Excel.  </p>
  
  <p>This is the code that I am using</p>
  
  <pre><code>public class Report
      {
          protected Workbook Workbook { get; set; }
          protected Application Excel { get; set; }
  
          public void RunReport()
          {
              // Launch Excel on the server
              Excel = new Application
              {
                  DisplayAlerts = false,
                  ScreenUpdating = false,
                  Visible = false
              };
  
              // Load the workbook template  
              Workbook = Excel.Workbooks.Open(@"D:\Book1.xlt");
  
              // Execute macros that generates the report, if any
              ExecuteMacros();
  
              Workbook.SaveAs(@"D:\Ray'sTesting.xls", XlFileFormat.xlExcel8);
              QuitExcel();
  
          }
          private void QuitExcel()
          {
              if (Workbook != null)
              {
                  Workbook.Close(false);
                  Marshal.ReleaseComObject(Workbook);
              }
  
              if (Excel != null)
              {
                  Excel.Quit();
                  Marshal.ReleaseComObject(Excel);
              }
          }        
          private void ExecuteMacros()
          {
  
  
              const string legacyModuleName = "Module1";
              const string legacyMacroName = "myMacro";
  
              bool legacyMacroExists = false;
              try
              {
                  var legacyMacroModule = Workbook.VBProject.VBComponents.Item(legacyModuleName);
                  if (legacyMacroModule != null)
                  {
                      int legacyMacroStartLine = legacyMacroModule.CodeModule.ProcStartLine[legacyMacroName, Microsoft.Vbe.Interop.vbext_ProcKind.vbext_pk_Proc];
                      legacyMacroExists = legacyMacroStartLine &gt; 0;
                  }
              }
              catch (Exception)
              {
                  legacyMacroExists = false;
              }
  
              if (!legacyMacroExists)
              {
                  return;
              }
  
              // VBA code for the dynamic macro that calls the CI2 legacy macro
              var moduleCode = new StringBuilder();
              moduleCode.AppendLine("Public Sub LaunchLegacyMacro()");
              moduleCode.AppendLine(string.Format("{0}.{1}", legacyModuleName, legacyMacroName));
              moduleCode.AppendLine("End Sub");
  
              // Add the dynamic macro to the ThisWorkbook module
              var workbookMainModule = Workbook.VBProject.VBComponents.Item("ThisWorkbook");
              workbookMainModule.CodeModule.AddFromString(moduleCode.ToString());
  
              // Execute the dynamic macro
              Microsoft.VisualBasic.Interaction.CallByName(Workbook, "LaunchLegacyMacro", Microsoft.VisualBasic.CallType.Method, new object[] { });
          }
      }
  </code></pre>