如何将任何操作从PC1中运行的一个应用程序传递到PC2中运行的不同应用程序

时间:2014-09-09 15:43:07

标签: c# winforms visual-studio-2010 visual-studio action

一个应用程序就是filewatcher,它一直在后台运行。它会在添加任何新文件时更新数据库。此应用程序仅更新数据库的两个字段。主键部分和**附件。 ** 同样,我有一个不同的主要应用程序,由不同PC中的不同用户处理。因此,当数据库中的任何新文件更新时,此应用程序有一个传输按钮。此按钮的操作使文件从单元格[2]移动到单元格[3]。这意味着它将所有文件从位置C:\ user \ fab移动到位置:C:\ user \ release。此应用程序没有任何文件监视器

所以我的问题是:

文件观察程序正在更新数据库的所有内容。但是当其他用户在单个**转移按钮的帮助下移动文件时按**。在另一台PC上运行的文件观察程序认为该文件已被删除,并且它接受删除数据库的命令。任何解决方案。请帮帮我。

链接第一部分:https://imageshack.com/i/idZuIKPnj

第二部分:https://imageshack.com/i/idJzeEtwj

代码段:

    private void OnChanged(object source, FileSystemEventArgs e)
    {

        switch (e.ChangeType)
        {
            case WatcherChangeTypes.Created:
                //Insert file in database
                this.Invoke(addItemInList, "File: " + e.FullPath + " Created");
                {
                    string filename = Path.GetFileName(e.FullPath);
                    filename = filename.Substring(0, filename.LastIndexOf("."));
                    SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
                    con.Open();
                    SqlCommand cmd = new SqlCommand(@"INSERT INTO cncinfo (part,draftpath) VALUES ('" + filename + "','" + e.FullPath + "') ", con);
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
                break;
            case WatcherChangeTypes.Deleted:
                //remove file from database
                this.Invoke(addItemInList, "File: " + e.FullPath + " Deleted");
                {
                    string filename = Path.GetFileName(e.FullPath);
                    filename = filename.Substring(0, filename.LastIndexOf("."));
                    SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
                    con.Open();
                    SqlCommand cmd = new SqlCommand(@"delete cncinfo where part='" + filename + "'  ;", con);
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
                break;
            case WatcherChangeTypes.Changed:
                ///if you are storing file in database(not file name whole file in binary format)
                ///then you can update the file in database here
                ///this event will be fired when any data has changed in the file.
                this.Invoke(addItemInList, "File: " + e.FullPath + " Changed");
                {
                    string filename = Path.GetFileName(e.FullPath);
                    filename = filename.Substring(0, filename.LastIndexOf("."));
                    SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
                    con.Open();
                    SqlCommand cmd = new SqlCommand(@"update cncinfo set part='" + filename
                        + "',draftpath='" + e.FullPath + "' where part='" + filename + "'", con);
                    cmd.ExecuteNonQuery();
                    con.Close();
                    this.Validate();
                }
                break;
        }
    }

    private void OnRenamed(object source, RenamedEventArgs e)
    {
        //Update then old filename with new here
        this.Invoke(addItemInList, string.Format("File: {0} renamed to {1}", e.OldFullPath, e.FullPath));
        {
            //string extension = e.FullPath.Substring(e.FullPath.LastIndexOf("."));
            string oldFileName = Path.GetFileName(e.OldFullPath);
            oldFileName = oldFileName.Substring(0, oldFileName.LastIndexOf("."));
            string filename = Path.GetFileName(e.FullPath);
            filename = filename.Substring(0, filename.LastIndexOf("."));
            SqlConnection con = new SqlConnection(@"Data Source=DVSQL\SQLEXPRESS;Initial Catalog=CncDB;User ID=CncDbUser;password=gcodedata");
            con.Open();
            SqlCommand cmd = new SqlCommand(@"update cncinfo set part='" + filename + "',draftpath='" + e.FullPath + "' where part='" + oldFileName + "'", con);
            cmd.ExecuteNonQuery();
            con.Close();
            this.Validate();
        }
    }

3 个答案:

答案 0 :(得分:0)

你的文件观察者只有3个动作。您的文件观察者是否以某种方式加载文件夹的历史记录?换句话说,如果文件观察程序不保留历史数据,则可以终止Filewatcher.exe,移动文件,然后重新启用。这种方法的问题是当exe关闭时你可能会错过文件夹中的更改或创建。

第二个解决方案是复制文件并将附加“FILEMOVED202”的原始文件或任何唯一字符串重命名到文件名的末尾,这样Test.doc将是TestFILEMOVED202.doc并将触发您的更改功能文件观察者。在更改的函数中,您可以将函数字符串的文件名字符串。如果它存在于更改函数中,则从文件观察器中删除实际文件,使用另一个标志禁止删除日志记录,并使用移动的值或其他任何内容更新数据库。

您在文件观察程序中唯一可以访问的是文件名,而不是文件内容,因此我会将其用作您的标记工具。

答案 1 :(得分:0)

转到第二个按下“传输”按钮的应用程序。使该代码将文件复制到传输目标,而不是移动它,以便删除函数永远不会触发。在文件副本重命名原始文件之后,将任何唯一字符串添加到文件名。像Test.docx一样会成为TestFileMovedTrans.doc。然后,这将触发您文件观察者的更改事件,它将进入上面的更改代码。在该更改代码中,检查唯一字符串“FileMovedTrans”的文件名或其他内容。如果它具有该字符串,则移动功能导致它&您可以记录并删除文件

删除更改代码中的文件后,将再次触发Filewatcher删除代码,您将再次检查文件名中的字符串。如果字符串存在,则不将其作为已删除状态记录到数据库,因为它仅被移动,如果字符串不在文件名中,则只使用常规的Delete功能。

答案 2 :(得分:0)

您还应该为移动文件的目标文件夹声明另一个filewatcher。但是,正如我告诉你你的ASP.NET室你必须签署该特定文件(即文件大小,修改日期和文件类型的组合)你可以创建一个类FileSignature

public class FileSignature
{
    public int FileSize { get; set; }
    public DateTime ModifiedDate { get; set; } //We could not take CreatedDate because it will be changed once the file moved but, modified date only change when it modified by editor (ie. notepad)
    public String FileType { get; set; }

    public String OldFileName { get; set; } //this is not the part of the combination of signature. It is just to get the old file name which is moved from.
}

并在发生删除文件事件时将该类的对象创建到列表中。

private List<FileSignature> movedList = new List<FileSignature>();
private void Watcher1_OnChange()
{
    ....
    case Delete:
        FileSignature singature = new FileSignature();
        FileInfo info = new System.IO.FileInfo(e.FullPath);
        signature.FileSize = info.Length;
        signature.ModifiedDate = info.LastWriteTime;
        singature.FileType = info.Extension;
        signature.OldFileName = e.FullPath;
        movedList.Add(signature);
        break;

}

FileInfo类将包含有关该文件的所有信息。

现在,您需要另一个FileWatcher对象作为目标文件夹路径(即C:\ user \ release)。

在第二个文件观察者OnChanged事件中,您将获得该文件已创建并从其他位置移动的事件。

private void Watcher2_OnChange()
{
    ....
    case Created:
        FileInfo info = new FileInfo(e.FullPath);
        FileSignature[] found = (from FileSignature sign in movedList 
                          where sign.ModifiedDate == info.LastWriteTime &&
                                sign.FileType == info.Extension &&
                                sign.FileSize == info.Length
                         select sign).ToArray()
        if (found.Length > 0)  //if the file found then it will be known as moved file otherwise created.
        {
            FileSignature signature = found[0]; //we will take only one file from the index 0. coz the file watcher event will occur for every file separately.
            //remove that file from the list first. So, further undeleted item in the list will be known as deleted at the end.
            movedList.Remove(signature);

            string oldFileName = signature.OldFileName; //this will contain full path of file which has been moved to new location.
            string newFileName = e.FullPath; //this will return new file name which is moved from source directory
            //Now you can perform you database update process here for move file. 
            //you have both path and flag that file is moved.
        } 
        else
        {
            //Now you can perform you database update process here for create file. 
        }

        break;    
}

现在,代码的主要部分在这里

现在您需要一个标志,当整个过程完成(文件移动)时,该标志将从主应用程序更新。您可以使用其他FileWatcher

当你从主应用程序获得进程已经定义的标志时,你可以调用另一种方法从数据库中删除movedList中存在的项目。

private void DeleteItems()
{
     foreach (FileSignature signature in movedList)
    {
         string filename = signature.OldFileName
         //Delete from the database. coz this files are known as deleted but not moved to destination 
    }
}