对话框不适用于SAP Business One加载项

时间:2013-06-11 09:39:22

标签: c# sap

我已将以下代码用于我的SAP Business One插件,该插件从对话框中读取Excel工作表。在测试我的插件时,我在

处设置了一个断点
Thread.Sleep(1);  // Wait a sec more
在Visual Studio 2012中

。这样就可以打开对话框,以便我可以选择Excel文件,因为在SAP中

  1. 必须在单独的线程上运行该对话框。
  2. 对于SAP客户端窗口的正确实例,对话框必须是模态的。
  3. 在Visual Studio中进行调试/测试时,插件运行正常,可以选择复制到矩阵的Excel工作表。 但是,当我使用.exe文件创建一个.ard以在SAP(一个可执行文件)中注册时,在我在对话框中选择一个excel文件(按OK)后,插件很快就会挂起。

    我在代码中做错了什么?#

    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)
                            {
    

    GetFileNameClass

    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
    {
    
        /// <summary>
        /// Wrapper for OpenFileDialog
        /// </summary>
        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
        }
    }
    

    任何帮助表示感谢。

1 个答案:

答案 0 :(得分:0)

您可以做的最简单的事情是不创建新线程,而是在方法GetFileHeader()中直接调用oGetFileName.GetFileName()

不需要新线程,因为看起来意图是应用程序应该等到文件被选中为止。

希望这会有所帮助 弗雷德里克