当重复选择文件或Excel格式的文件时,会引发此异常

问题描述 投票:-2回答:1

问候朋友,

FileStream或Process,请帮助弄清楚。

以下Windows窗体应用程序首先从openFileDialog1中选择一个或多个文件,检查这些文件是否在数据库中(GetInsertNummer),然后将它们写入数据库(InsertInTable)。

然后,它从数据库读取它们并在Windows(FileGetSimple)中写入。接下来,打开,关闭这些文件,然后通过电子邮件(CreateMessage)发送这些文件。

一切似乎都正常,但是当反复选择文件或Excel格式的文件时,会引发此异常。

该进程无法访问文件”,因为它正在被另一个进程使用。

[运行程序时,我只按了一次按钮(btnSales_Click。)第一次,一切正常。

using System;
using System.IO;
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.Data.SqlClient;
using System.Globalization;
using System.Diagnostics;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Net.Mime;
//using System.Threading.Tasks;


namespace GebrNaimSalesWindowsForms
{
    public partial class Form1 : Form
    {
        //SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-E2S6MTB\SQLEXPRESS;Initial Catalog=GebrNaimProject;Integrated Security=True");

        //SqlDataAdapter adapt;
        //public string[] files { get; set; }
        public List<string> files { get; set; }
        public List<string> outputfiles { get; set; }
        public int insertNummer;
        public int row_id;
        public Process sp;
        public string ExceptionMessage { get; set; }

        public Form1()
        {
            InitializeComponent();
            //DisplayData();
        }

        //Display Data in DataGridView  
        //private void DisplayData()
        //{
        //    con.Open();
        //    DataTable dt = new DataTable();
        //    adapt = new SqlDataAdapter("select * from StoredFile", con);
        //    adapt.Fill(dt);
        //    dataGridView1.DataSource = dt;
        //    con.Close();
        //}
        private void btnSales_Click(object sender, EventArgs e)
        {
            outputfiles = null;
            files = null;
            sp = null;

            //sp.Refresh();

            if (InformationWindow("Выбирете пожалйста фалы и сохраните в Windows", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.OK)
            {

                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    foreach (var item in openFileDialog1.FileNames)
                    {
                        //files.Add(item);

                        files = new List<string>();
                        files.Add(item);

                    }


                }
                else
                {
                    files = null;
                }

                GetInsertNummer(@"SELECT (SELECT MAX(id) FROM StoredFile) id, MAX(InsertNummer) InsertNummer
FROM StoredFile");

                if (files != null)
                {
                    for (int i = 0; i < files.Count; i++)
                    {
                        InsertInTable(i);

                        row_id++;


                        FileGetSimple(row_id, files[i]);

                    }
                    InformationWindow("Все в порядке с выбранными файлами?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    CreateMessage("smtp.strato.de");

                    MessageBox.Show("success");


                }

                //DisplayData();


            }


        }

        public DialogResult InformationWindow(string v1, string v2, MessageBoxButtons oKCancel, MessageBoxIcon information)
        {
            string message = v2;
            string caption = v1;
            MessageBoxButtons buttons = oKCancel;
            DialogResult result;

            // Displays the MessageBox.
            return result = MessageBox.Show(message, caption, buttons, information);
        }



        public void CreateMessage(string server)
        {
            using (SmtpClient client = new SmtpClient(server))
            {

                client.Port = 587;
                client.EnableSsl = true;

                client.Credentials = new NetworkCredential("[email protected]", "");

                MailAddress from = new MailAddress("---",--- );
                MailAddress to = new MailAddress("---", ---);
                MailMessage message = new MailMessage(from, to);

                // message.Subject = "Using the SmtpClient class.";
                message.Subject = "Es funktioniert.";
                message.Body = @"Вы получили письмо с вложением";

                foreach (var item in outputfiles)
                {
                    if (!sp.HasExited)
                    {
                        //sp.WaitForExit();
                        sp.Kill();


                        //if (Marshal.IsComObject(sp))
                        //{
                        //    Marshal.ReleaseComObject(sp);
                        //}


                        //Marshal.ReleaseComObject(sp);
                    }
                    else
                        sp = null;
                    //sp.WaitForExit();
                    //sp.Close();

                    //Process[] ps2 = System.Diagnostics.Process.GetProcessesByName("EXCEL");
                    //foreach (Process p2 in ps2)
                    //{
                    //    Marshal.ReleaseComObject(p2);
                    //    p2.Kill();
                    //}

                    message.Attachments.Add(new Attachment(item));


                }


                InformationWindow("Success", $"Sending an email message to" + to.Address + " by using the SMTP host " + client.Host + ".", MessageBoxButtons.OK, MessageBoxIcon.Information);

                try
                {
                    client.Send(message);
                }
                catch (Exception ex)
                {
                    // Me.WriteLine("Exception caught in CreateCopyMessage(): {0}",ex.ToString());
                    InformationWindow("Exception", ex.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
               //
            }
        }



//using(SmtpClient smtpClient = new SmtpClient())
//{
//    var basicCredential = new NetworkCredential("username", "password"); 
//    using(MailMessage message = new MailMessage())
//    {
//        MailAddress fromAddress = new MailAddress("[email protected]");

//        smtpClient.Host = "mail.mydomain.com";
//        smtpClient.UseDefaultCredentials = false;
//        smtpClient.Credentials = basicCredential;

//        message.From = fromAddress;
//        message.Subject = "your subject";
//        // Set IsBodyHtml to true means you can send HTML email.
//        message.IsBodyHtml = true;
//        message.Body = "<h1>your message body</h1>";
//        message.To.Add("[email protected]"); 

//        try
//        {
//            smtpClient.Send(message);
//        }
//        catch(Exception ex)
//        {
//            //Error, could not send the message
//            Response.Write(ex.Message);
//        }
//    }
//}



        private void InsertInTable(int i)
        {
            // **** Write BLOB to the Database
            byte[] filebyte = File.ReadAllBytes(files[i]);

            string sql = @"insert into StoredFile(FileName,Data,InsertNummer,Date) values(@FileName,@Data,@InsertNummer,@Date)";

            var cmd = MakeConnection(sql);

            SqlParameter parameter1 = cmd.Parameters.AddWithValue("@FileName", Path.GetFileName(files[i]));
            SqlParameter parameter2 = cmd.Parameters.AddWithValue("@Data", filebyte);
            SqlParameter parameter3 = cmd.Parameters.AddWithValue("@InsertNummer", insertNummer);
            SqlParameter parameter4 = cmd.Parameters.AddWithValue("@Id", row_id);
            SqlParameter parameter5 = cmd.Parameters.AddWithValue("@Date", DateTime.Now);


            cmd.ExecuteNonQuery();



        }

        public bool FileGetSimple(int Identifier, string filePath)
        {
            var pa = Path.Combine(Path.GetTempPath(), Path.GetFileName(filePath));

            var statement = "SELECT Id, Data, FileName FROM StoredFile WHERE Id = @id;";
            var mc = MakeConnection(statement);


            mc.Parameters.AddWithValue("@id", Identifier);
            SqlDataReader reader = mc.ExecuteReader();

            if (reader.HasRows)
            {
                reader.Read();

                // the blob field
                int ndx = reader.GetOrdinal("Data");

                var blob = new Byte[(reader.GetBytes(ndx, 0, null, 0, int.MaxValue))];

                reader.GetBytes(ndx, 0, blob, 0, blob.Length);
                reader.Close();

                try
                {
                    //using (var fs = new FileStream(pa, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                    //{
                    //    fs.Write(blob, 0, blob.Length);
                    //}

                    if (File.Exists(pa))
                    {
                        File.Delete(pa);
                    }

                    using (var fs = new FileStream(pa, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                    {
                        fs.Write(blob, 0, blob.Length);

                    }




                    //using (FileStream fs = File.Create(pa))
                    //{
                    //    fs.Write(blob, 0, blob.Length);
                    //}

                    //using (var stream = File.Create(pa))
                    //{
                    //File.WriteAllBytes(pa, blob);
                    //}
                }
                catch (IOException e) {
                    InformationWindow("Warning", e.Message + " Schlie&#223;en Sie diese Datei, um fortzusetzen.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    FileGetSimple(Identifier, filePath);
                }





            }



            OpenFiles(pa);

            return true;

        }

        private void OpenFiles(string tempFilePath)
        {


            using (sp = new Process())
            {
                sp = Process.Start(tempFilePath);
            }



            outputfiles = new List<string>();
            outputfiles.Add(tempFilePath);

        }

        public void GetInsertNummer(string ins_num_query)
        {

            var ins_num = MakeConnection(ins_num_query);
            SqlDataReader read_ins_nummer = ins_num.ExecuteReader();

            while (read_ins_nummer.Read())
            {
                int ins = read_ins_nummer.GetOrdinal("InsertNummer");
                int ins_id = read_ins_nummer.GetOrdinal("Id");
                if (!read_ins_nummer.IsDBNull(read_ins_nummer.GetOrdinal("InsertNummer")))
                {
                    insertNummer = read_ins_nummer.GetInt32(ins);
                    row_id = read_ins_nummer.GetInt32(ins_id);
                    insertNummer++;
                }
                else
                {
                    insertNummer = 1;
                    row_id = 0;
                }

            }
        }



        public SqlCommand MakeConnection(string sql)
        {

            SqlConnection connection = new SqlConnection(Properties.Settings.Default.connection_str);
            connection.Open();


            using (SqlCommand cmd = new SqlCommand() { Connection = connection, CommandText = sql })
            {
                try
                {
                    return cmd;

                }
                catch (Exception ex)
                {

                    ExceptionMessage = ex.Message;
                    return cmd;
                }
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //this.Close();
            Application.Exit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'gebrNaimProjectDataSet.StoredFile' table. You can move, or remove it, as needed.
            //this.storedFileTableAdapter.Fill(this.gebrNaimProjectDataSet.StoredFile);

        }
    }
}
c# windows winforms filestream sqldatareader
1个回答
0
投票

查看您的代码(在注释中:):

    public partial class Form1 : Form
    {
        public List<string> files { get; set; }
        public List<string> outputfiles { get; set; }

        // these fields are public but not properties, why?
        public int insertNummer;
        public int row_id;
        public Process sp;
        public string ExceptionMessage { get; set; }

        public Form1()
        {
            InitializeComponent();
        }

        private void btnSales_Click(object sender, EventArgs e)
        {
            outputfiles = null;
            files = null;
            sp = null;

            // didn't compile
            if (InformationWindow("Выбирете пожалйста фалы и сохраните в Windows", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.OK)
            {
                // invert and return
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    foreach (var item in openFileDialog1.FileNames)
                    {
                        files = new List<string>();
                        files.Add(item);
                    }
                }
                else
                {
                    // useless since files is already null at this point
                    files = null;
                }

                GetInsertNummer(@"SELECT (SELECT MAX(id) FROM StoredFile) id, MAX(InsertNummer) InsertNummer FROM StoredFile");

                // useless if return above
                if (files != null)
                {
                    for (int i = 0; i < files.Count; i++)
                    {
                        InsertInTable(i);

                        // use ++row_id in FileGetSimple instead
                        row_id++;

                        FileGetSimple(row_id, files[i]);
                    }
                    // doesn't compile
                    InformationWindow("Все в порядке с выбранными файлами?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    CreateMessage("smtp.strato.de");

                    MessageBox.Show("success");
                }
            }
        }

        public DialogResult InformationWindow(string v1, string v2, MessageBoxButtons oKCancel, MessageBoxIcon information)
        {
            // bad practise, rename v1 to caption and v2 to message in method parameter
            string message = v2;
            string caption = v1;
            // unnecessary variable definitions, also weird name "oKCancel" for dynamically assigned MessageBoxButtons that aren't always Ok/Cancel?
            MessageBoxButtons buttons = oKCancel;
            DialogResult result;

            // Displays the MessageBox.
            // return the value directly instead of an unneeded assignment
            return result = MessageBox.Show(message, caption, buttons, information);
        }

        public void CreateMessage(string server)
        {
            using (SmtpClient client = new SmtpClient(server))
            {
                client.Port = 587;
                client.EnableSsl = true;

                client.Credentials = new NetworkCredential("[email protected]", "");

                // didn't compile ---
                MailAddress from = new MailAddress("---", "");
                MailAddress to = new MailAddress("---", "");
                MailMessage message = new MailMessage(from, to);

                message.Subject = "Es funktioniert.";
                // unnecessary @
                message.Body = @"Вы получили письмо с вложением";

                // outputfiles will always only contain a single file --> the loop will only run once, ever!
                foreach (var item in outputfiles)
                {
                    // dispose of possibly previously disposed process, not necessary or using statement of sp not necessary
                    if (!sp.HasExited)
                    {
                        sp.Kill();
                    }
                    else
                        sp = null;

                    message.Attachments.Add(new Attachment(item));
                }

                InformationWindow("Success", $"Sending an email message to" + to.Address + " by using the SMTP host " + client.Host + ".", MessageBoxButtons.OK, MessageBoxIcon.Information);

                try
                {
                    client.Send(message);
                }
                catch (Exception ex)
                {
                    InformationWindow("Exception", ex.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void InsertInTable(int i)
        {
            // **** Write BLOB to the Database
            byte[] filebyte = File.ReadAllBytes(files[i]);

            // unnecessary variable declaration (it's only used once), put statement directly in MakeConnection("...")
            string sql = @"insert into StoredFile(FileName,Data,InsertNummer,Date) values(@FileName,@Data,@InsertNummer,@Date)";

            var cmd = MakeConnection(sql);

            // unnecessary variable declarations, parameter1..5 is never used anywhere
            SqlParameter parameter1 = cmd.Parameters.AddWithValue("@FileName", Path.GetFileName(files[i]));
            SqlParameter parameter2 = cmd.Parameters.AddWithValue("@Data", filebyte);
            SqlParameter parameter3 = cmd.Parameters.AddWithValue("@InsertNummer", insertNummer);
            SqlParameter parameter4 = cmd.Parameters.AddWithValue("@Id", row_id);
            SqlParameter parameter5 = cmd.Parameters.AddWithValue("@Date", DateTime.Now);

            cmd.ExecuteNonQuery();
        }

        public bool FileGetSimple(int Identifier, string filePath)
        {
            // why did you start using var instead of the types?
            var pa = Path.Combine(Path.GetTempPath(), Path.GetFileName(filePath));

            var statement = "SELECT Id, Data, FileName FROM StoredFile WHERE Id = @id;";
            var mc = MakeConnection(statement);

            mc.Parameters.AddWithValue("@id", Identifier);
            SqlDataReader reader = mc.ExecuteReader();

            if (reader.HasRows)
            {
                reader.Read();

                // the blob field
                int ndx = reader.GetOrdinal("Data");

                // that is wrong and not how to read a buffer, read up on how to use buffers/GetBytes correctly!
                var blob = new Byte[(reader.GetBytes(ndx, 0, null, 0, int.MaxValue))];
                // oh jeez
                reader.GetBytes(ndx, 0, blob, 0, blob.Length);
                reader.Close();

                try
                {
                    if (File.Exists(pa))
                    {
                        File.Delete(pa);
                    }

                    using (var fs = new FileStream(pa, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                    {
                        fs.Write(blob, 0, blob.Length);
                    }
                }
                catch (IOException e)
                {
                    InformationWindow("Warning", e.Message + " Schlie&#223;en Sie diese Datei, um fortzusetzen.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    FileGetSimple(Identifier, filePath);
                }
            }

            // function is called OpenFiles but only a single file is supplied?
            OpenFiles(pa);

            return true;
        }

        private void OpenFiles(string tempFilePath)
        {
            // what is this even supposed to do?
            // create new process instance
            using (sp = new Process())
            {
                // then throw away the instance and start a process instead
                sp = Process.Start(tempFilePath);
                // then dispose process
            }
            // quiz: has new Process() or Process.Start been disposed by the using statement?

            // every time a file is opened the outputfiles list is re-initialized and a single element is addded?
            // it's never going to contain more than one element!
            outputfiles = new List<string>();
            outputfiles.Add(tempFilePath);
        }

        public void GetInsertNummer(string ins_num_query)
        {
            // using dynamic sql statements but accessing columns statically, how do you guarantee that these columns exist?
            // is there a point in providing a parameter, why can the statement not be inside this function, it never changes!
            var ins_num = MakeConnection(ins_num_query);
            SqlDataReader read_ins_nummer = ins_num.ExecuteReader();

            while (read_ins_nummer.Read())
            {
                int ins = read_ins_nummer.GetOrdinal("InsertNummer");
                int ins_id = read_ins_nummer.GetOrdinal("Id");
                // use previously defined variable "ins" instead of re-executing GetOrdial
                if (!read_ins_nummer.IsDBNull(read_ins_nummer.GetOrdinal("InsertNummer")))
                {
                    // insertNummer and row_id is the same, dont' execute GetInt32 twice, use the same value instead!
                    insertNummer = read_ins_nummer.GetInt32(ins);
                    row_id = read_ins_nummer.GetInt32(ins_id);
                    insertNummer++;
                }
                else
                {
                    insertNummer = 1;
                    row_id = 0;
                }
            }
        }

        public SqlCommand MakeConnection(string sql)
        {
            SqlConnection connection = new SqlConnection("");
            connection.Open();

            // you're using object initializer here, why not everywhere else?
            using (SqlCommand cmd = new SqlCommand() { Connection = connection, CommandText = sql })
            {
                try
                {
                    return cmd;
                }
                catch (Exception ex)
                {
                    // this is never used anywhere
                    ExceptionMessage = ex.Message;
                    return cmd;
                }
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }

很难阅读,甚至更难弄清楚应该发生什么。看起来像是从不同教程/ stackoverflow帖子中复制/粘贴frankencode。 YOU知道发生了什么吗? I应该如何?

也,

FileStream或Process,请帮助弄清楚

你怎么不知道?您正在获取异常,您应该知道异常发生的位置。

抱歉,此答案没有用,但可能是您得到的最好的答案。提供minimal, reproducible example,然后再次询问。

© www.soinside.com 2019 - 2024. All rights reserved.