title: Dialog box does not work for SAP Business One Add-On
body: <p>I have used the code below for my SAP Business One add-on that reads Excel sheets from a dialog box. While testing my addon, I placed a breakpoint at </p>
  
  <pre><code>Thread.Sleep(1);  // Wait a sec more
  </code></pre>
  
  <p>in Visual Studio 2012. This enables the dialog box to open so that I can select the Excel file because in SAP</p>
  
  <ol>
  <li>The dialog must be run on a separate thread.</li>
  <li>The dialog must be modal for the correct instance of the SAP client window.</li>
  </ol>
  
  <p>While debugging/testing in Visual Studio, the addon runs fine and can select an Excel sheet which copies to a matrix.
  However, when I make an .ard with .exe file to register in SAP (an executable file), the addon hangs soon after I choose an excel file (press OK) on the dialog box.</p>
  
  <p>What am I doing wrong in the code?#</p>
  
  <pre><code>private void GetFileHeader()
          {
              using (GetFileNameClass oGetFileName = new GetFileNameClass())
              {
                  oGetFileName.Filter = "Excel files (*.csv)|*.csv";
                  oGetFileName.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                  Thread threadGetExcelFile = new Thread(new ThreadStart(oGetFileName.GetFileName));
                  threadGetExcelFile.SetApartmentState(ApartmentState.STA);
  
                  try
                  {
                      threadGetExcelFile.Start();
                      while (!threadGetExcelFile.IsAlive) ; // Wait for thread to get started
                      Thread.Sleep(1); // Wait a sec more
                      threadGetExcelFile.Join(); // Wait for thread to end
  
                      var fileName = string.Empty;
                      fileName = oGetFileName.FileName;
  
                      if (fileName != string.Empty)
                      {
                          string connString = "";
                          System.Data.DataTable dt = new System.Data.DataTable();
  
                          // Initialize connection string
                          connString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES\"", fileName);
  
                          // Connect
                          OleDbConnection myConnection = new OleDbConnection(connString);
  
                          // Open connection if closed
                          if (myConnection.State != ConnectionState.Open)
                              myConnection.Open();
  
                          string fName = fileName;
  
                          fName = System.IO.Path.GetFileNameWithoutExtension(fName);
  
                          string sql = "SELECT * FROM [" + fName + "$] WHERE RecordKey IS NOT NULL";
  
                          OleDbCommand cmd = new OleDbCommand(sql, myConnection);
                          cmd.CommandType = CommandType.Text;
  
                          OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
  
                          adapter.Fill(dt);
  
                          if (dt != null)
                          {
  </code></pre>
  
  <p>The GetFileNameClass</p>
  
  <pre><code>using System;
  using System.Diagnostics;
  using System.Windows.Forms;
  using System.Threading;
  using System.Runtime.InteropServices;
  
  namespace SBOPlugins.Enumerations
  {
      public enum eFileDialog { en_OpenFile = 0, en_SaveFile = 1 };
  }
  
  namespace CoreFrieght_Intraspeed
  {
  
      /// &lt;summary&gt;
      /// Wrapper for OpenFileDialog
      /// &lt;/summary&gt;
      public class GetFileNameClass : IDisposable
      {
          #region The class implements FileDialog for open in front of B1 window
  
          [DllImport("user32.dll")]
          private static extern IntPtr GetForegroundWindow();
  
          System.Windows.Forms.FileDialog _oFileDialog;
  
          // Properties
          public string FileName
          {
              get { return _oFileDialog.FileName; }
              set { _oFileDialog.FileName = value; }
          }
  
          public string[] FileNames
          {
              get { return _oFileDialog.FileNames; }
          }
  
          public string Filter
          {
              get { return _oFileDialog.Filter; }
              set { _oFileDialog.Filter = value; }
          }
  
          public string InitialDirectory
          {
              get { return _oFileDialog.InitialDirectory; }
              set { _oFileDialog.InitialDirectory = value; }
          }
  
          //// Constructor
          //public GetFileNameClass()
          //{
          //    _oFileDialog = new OpenFileDialog();
          //}
  
          // Constructor
          public GetFileNameClass(SBOPlugins.Enumerations.eFileDialog dlg)
          {
              switch ((int)dlg)
              {
                  case 0: _oFileDialog = new System.Windows.Forms.OpenFileDialog(); break;
                  case 1: _oFileDialog = new System.Windows.Forms.SaveFileDialog(); break;
                  default: throw new ApplicationException("GetFileNameClass Incorrect Parameter");
              }
          }
  
          public GetFileNameClass()
              : this(SBOPlugins.Enumerations.eFileDialog.en_OpenFile)
          {
  
          }
  
          // Dispose
          public void Dispose()
          {
              _oFileDialog.Dispose();
          }
  
          // Methods
  
          public void GetFileName()
          {
              IntPtr ptr = GetForegroundWindow();
  
              WindowWrapper oWindow = new WindowWrapper(ptr);
  
              if (_oFileDialog.ShowDialog(oWindow) != System.Windows.Forms.DialogResult.OK)
              {
                  _oFileDialog.FileName = string.Empty;            
              }
              oWindow = null;
          } // End of GetFileName
  
          #endregion
  
          #region WindowWrapper : System.Windows.Forms.IWin32Window
  
          public class WindowWrapper : System.Windows.Forms.IWin32Window
          {
              private IntPtr _hwnd;
  
              // Property
              public virtual IntPtr Handle
              {
                  get { return _hwnd; }
              }
  
              // Constructor
              public WindowWrapper(IntPtr handle)
              {
                  _hwnd = handle;
              }
          }
          #endregion
      }
  }
  </code></pre>
  
  <p>Any help appreciated.</p>