有没有办法正确结束与QuickBooks/QBW32.exe的会话,所以它不会在后台运行?

Ste*_*hen 5 c# session quickbooks qbxml

我在许多程序上执行技术支持和一些开发,这些程序使用QuickBooks SDK来执行各种功能.最近我注意到当用户执行以下操作时:

先决条件: - QuickBooks未在桌面上打开,并且当前未运行. - 我的桌面程序未在QuickBooks集成应用程序列表中设置以自动登录.

1)打开我的一个程序.

2)执行启动与QuickBooks的连接和会话的操作.

3)QuickBooks界面返回一个错误,指出您必须打开QuickBooks并登录到公司文件才能执行此操作.

4)我的程序关闭会话和连接,然后向用户显示一些对话框,为他们提供故障排除提示.

结果:

QuickBooks本身继续作为QBW32.exe在后台运行,即使会话和连接都已关闭.

如果用户然后尝试打开QuickBooks桌面程序,则会收到错误消息,告诉他们QuickBooks已在运行.然后,他们必须在Windows中打开任务管理器并关闭正在运行的QBW32.exe,然后才能成功打开QuickBooks.

我已经使用我在下面编写的非常基本的C#程序重现了这一点.

在测试应用程序中,我使用以下步骤/方案:

先决条件:1)测试应用程序未设置为自动登录到QuickBooks.它设置为仅在用户打开QuickBooks桌面程序并且具有打开的公司文件时登录.

2)确保在下面的测试之前没有打开QuickBooks.

脚步:

1)打开测试C#应用程序

2)按下"打开连接"按钮.应通过QBXML互操作与QuickBooks的界面打开连接.

3)按"开始会话"按钮.应该使用QuickBooks启动会话.

4)假设上面的测试预先请求已经满足,您应该收到QuickBooks返回的错误消息,告诉您应用程序未设置为自动登录,您需要先打开QuickBooks才能尝试会话.

5)QBW32.exe现在应该在后台运行.

6)按下结束会话的按钮.这应该使用QuickBooks界面结束会话.无论如何,会话应该已经通过步骤3按钮中的try-catch结束.

7)按"关闭连接"按钮.这应该关闭与QuickBooks的所有连接.

8)即使会话和连接已经结束并关闭,QBW32.exe仍然在后台运行.

9)使用退出按钮关闭测试应用程序.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using Interop.QBXMLRP2;

namespace Open_Connection
{

    public partial class Form1 : Form
    {

        bool sessionBegun = false;
        bool connectionOpen = false;
        RequestProcessor2 rp = null;
        string ticket;


        public Form1()
        {
            InitializeComponent();
        }

        private void End_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void OpenConn_Click(object sender, EventArgs e)
        {
            try
            {  //Start a new connection with QuickBooks
                rp = new RequestProcessor2();
                rp.OpenConnection2("", "Open Connection", QBXMLRPConnectionType.localQBD);
                connectionOpen = true;
            }

            catch (Exception connectionException)
                { //If the connection fails, close the connection to avoid the program from getting stuck in an interop error loop.
                        MessageBox.Show(connectionException.Message, "Error");
                        if (connectionOpen)
                        {
                            rp.CloseConnection();
                        }
                }
        }

        private void StartSess_Click(object sender, EventArgs e)
        {
            try
            {  //Start a new session with QuickBooks using the company file specified below.
                string ticket = rp.BeginSession(@"C:\Users\username\Documents\Quickbooks Company Files\example.QBW", QBFileMode.qbFileOpenDoNotCare);
                sessionBegun = true;
            }
            catch (Exception sessException)
            {
                //If the session fails (I.E. QuickBooks is not open with a user logged into the company file and the program is not given permission to
                //automatically log in, imeedietly end the session and close the connection.
                MessageBox.Show(sessException.Message, "Error");
                if (sessionBegun)
                {
                    rp.EndSession(ticket);
                }

                if (connectionOpen)
                {
                    rp.CloseConnection();
                }
            }
        }

        private void EndSess_Click(object sender, EventArgs e)
        {
            try
            { //End the session 
                rp.EndSession(ticket);
                sessionBegun = false;
            }

            catch (Exception ex)
            { //If a session was not started already, set the session begun flag to false to avoid getting stuck in a loop. 
                sessionBegun = false;
            }

        }

        private void CloseConn_Click(object sender, EventArgs e)
        {
            try
            { //Close the connection to QuickBooks 
                rp.CloseConnection();
                connectionOpen = false;
            }

            catch (Exception ex)
            { //If the connection was not open, set the connection open flag ot false to avoid getting stuck in a loop.
                connectionOpen = false;
            }

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我上面提到的示例程序,有什么东西我可以做QBW32.exe自己关闭所以它不会在我上面描述的场景下继续在后台运行?

更新:我自己和许多其他用户已经尝试在QuickBooks的首选项部分中关闭"保持Quickbooks运行以加快启动"的设置.在会话和连接都结束后,这不会阻止QBW32.exe在后台保持打开状态.我看到QB 2013到2015年会出现这种情况.

Ste*_*hen 4

在使用 Geetanjali 提出的场景做了一些进一步的测试后,我得出了这个结论:

  • 仅当您在 QB 中的集成应用程序列表中设置程序以自动登录时,QBW32.exe 才会自行关闭。

  • 如果您的程序未设置为自动登录,则 QBW32.exe 将在您传入公司文件名时启动会话时打开,并且即使您结束会话并结束连接,QBW32.exe 也将保持打开状态。

  • 如果启动会话时没有传入公司文件,QBW32.exe 不会启动。

我已经在 Intuit 论坛上向 William 确认了这一点,这似乎正在按预期进行。

为了解决这个问题,我在我的测试应用程序中做到了这一点:

我在会话开始周围添加了一个额外的 if 块,以便首先通过未指定公司文件的开放会话调用发送连接测试。这会强制界面返回错误,告诉我无法启动会话,因为未指定公司文件且 QuickBooks 未打开。这随后迫使我的测试应用程序显示一条消息,告诉我在重试之前打开公司文件。

我想我可以通过添加“在自动模式下使用日志”和“常规模式”设置来进一步构建这一点,以便如果我确实想在自动模式下使用日志,则可以在需要时跳过测试连接。

无论如何,除了添加终止 QBW32.exe 进程的代码块之外,这似乎是解决这种情况的唯一方法。这并不完全是可取的,但也是一种选择。

无论如何,我希望这可以帮助任何在不久的将来遇到这个障碍的人。

截至 2017 年 9 月 12 日更新:

似乎从 QuickBooks 2016 开始,这种行为不再是问题。无论您是否传递带有或不带有自动登录的公司文件,当您启动会话时,当用户尝试直接或通过桌面/开始菜单快捷方式运行可执行文件时,QBW32.exe 将随后打开( s)。有趣的是,QBW32.exe 进程可能已经在后台运行,因为您传入了公司文件而没有自动登录。尽管如此,用户仍然可以打开 QuickBooks,并且不会收到表明 QuickBooks 已在运行的消息。

我已经使用 QuickBooks Enterprise 2016 和 Enterprise 2017 对此进行了测试。我们所有至少拥有 QuickBooks 2016(各种版本、Pro、Premier 等)的用户也没有抱怨上述问题。我在这里冒险猜测 Intuit 有意无意地决定解决这个问题。

因此,如果您或集成应用程序的用户仍在使用低于 QuickBooks 2016 的 QuickBooks 版本,我仅建议您使用上述方法。