简体   繁体   中英

How can I activate the previously opened microsoft access instance of an app using C#?

I'm using this code to open an access database :

public partial class Start_Baseet : System.Windows.Forms.Form
{
string MyFile = Environment.CurrentDirectory + "\\Baseet.accde";
Microsoft.Office.Interop.Access.Application AccApp = new Microsoft.Office.Interop.Access.Application();

public Start_Baseet()
{
    InitializeComponent();
}
public void OpenDb()
{
  
        AccApp.Visible = true;
        AccApp.OpenCurrentDatabase(MyFile, false, "017014a");
        AccApp.RunCommand(AcCommand.acCmdAppMaximize);
        // AccApp.Activate();


    }
}
      

private void Start_Basset_Load(object sender, EventArgs e)
{
    try
    {
        OpenDb();
    }
    catch
    {
        AccApp.Quit();
        MessageBox.Show("Something is missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
    }
    finally
    {
        this.Close();
        System.Windows.Forms.Application.Exit();
        System.Windows.Forms.Application.ExitThread();
        // Process.GetCurrentProcess().CloseMainWindow();
    }

The problem is the MSACCESS process is piling up in the running processes so I tried this :

  //var prc = Process.GetProcessesByName("MSACCESS.EXE*32");
        var prc = Process.GetProcessesByName("Microsoft Access");
        if (prc.Length > 0)
        {
            MessageBox.Show("Access Found");
            SetForegroundWindow(prc[0].MainWindowHandle);
        }
        else
        {
            AccApp.Visible = true;
            AccApp.OpenCurrentDatabase(MyFile, false, "017014a");
            AccApp.RunCommand(AcCommand.acCmdAppMaximize);
            // AccApp.Activate();


        }
    }
    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

But still with every time I use the code another MSACCESS process starts. How can I fix this ? Other point if I ran my app second time it will open a new instance of the same database can I activate the database if it is opened otherwise open a new instance of it ? Thanks

Try this. This should catch users closing out Access as well through error catching. I'm sure it can be improved on but, I don't get a bunch of MSAccess.exe in the background from this code I wrote a while ago.

public partial class Form1 : Form
{
    Microsoft.Office.Interop.Access.Application accApp = new Microsoft.Office.Interop.Access.Application();
    private bool isFormClosed = false; 

    public Form1()
    {
        InitializeComponent();
        OpenMicrosoftAccessFile(@"FileName");

        Thread t = new Thread(new ThreadStart(CheckIfMSAccessExeIsRunning)); 
        t.Start();
    }

    /// <summary>
    /// The User Closed Out Access Cleanup.
    /// </summary>
    public void CheckIfMSAccessExeIsRunning()
    {
        int secondsToWait = 5*1000;
        while(!isFormClosed)
        {
            if (accApp != null && 
                accApp.Visible == false)
                CloseMicrosoftAccessFile();
            Thread.Sleep(secondsToWait);
        }
        CloseMicrosoftAccessFile();
    }

    private bool OpenMicrosoftAccessFile(string accessFileName)
    {
        try
        {
            if (accApp != null &&
                !accApp.Visible)
            {
                CloseMicrosoftAccessFile();
            }

            if (accApp == null)
            {
                accApp = new Microsoft.Office.Interop.Access.Application();

                accApp.OpenCurrentDatabase(accessFileName);

                accApp.Visible = true;
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine((ex.InnerException != null) ? ex.InnerException : "");
            CloseMicrosoftAccessFile();
            return false;
        }
    }

    private void CloseMicrosoftAccessFile()
    {
        try
        {
            if (accApp != null)
            {
                accApp.CloseCurrentDatabase();
                accApp.Quit();
            }
        }
        catch (Exception ex)
        {
            //Good chance there never was an Access exe.
            Console.WriteLine(ex.Message);
            Console.WriteLine((ex.InnerException != null) ? ex.InnerException : "");
        }
        finally
        {

            System.Runtime.InteropServices.Marshal.ReleaseComObject(accApp);
            accApp = null;

        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        isFormClosed = true;
    }
}

Also, if you still have processes running the Debugger or Visual Studio is probably holding onto it still. It would be good to test this from the release exe. If OpenMicrosoftAccessFile returns false you can try opening it up again but, this way ignores the error it caught.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM