3

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

Thread.Sleep(1);  // Wait a sec more

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

  1. 该对话框必须在单独的线程上运行。
  2. 对于 SAP 客户端窗口的正确实例,对话框必须是模态的。

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

获取文件名类

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
    }
}

任何帮助表示赞赏。

4

1 回答 1

0

The simplest thing you can do is to not to create a new thread, but instead, in the method GetFileHeader(), call oGetFileName.GetFileName() directly.

The new thread is not needed because it seems that the intent is that the application should wait until the file is chosen anyway.

Hope this helps Fredrik

于 2013-06-20T08:24:48.960 回答