none
C#做服务程序想实现删除文件到回收站应该怎么做? RRS feed

答案

  • 回收站是资源管理器API的一部分,资源管理器的API都是不支持在服务下运行的。

    你可以写个代理程序在用户登录的时候运行,在代理程序里删除文件。



    Visual C++ MVP

    2019年5月7日 16:30
    版主

全部回复

  • 首先添加Microsoft.VisualBasic引用

    程序中引用 Microsoft.VisualBasic.FileIO 来进行处理


     Console.WriteLine("删除文件到回收站");
                string filepath = @"C:\Users\wppcn\Desktop\新建文本文档.txt";
                FileSystem.DeleteFile(filepath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                Console.WriteLine("删除文件完成");
    
                Console.WriteLine("删除文件夹到回收站");
                string dirpath = @"C:\Users\wppcn\Desktop\新建文件夹";
                FileSystem.DeleteDirectory(dirpath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                Console.WriteLine("删除文件夹完成");




    • 已编辑 ARM830 2019年5月6日 2:37
    2019年5月6日 2:32
  • 这个不支持在  Windows Services 运行啊 
    2019年5月6日 3:24
  • 你应该使用windows api:SHFileOperation,用法网上多的是,请自己搜索一下吧。
    • 已建议为答案 ARM830 2019年5月6日 11:40
    2019年5月6日 8:16
  • Hi  Chihwei Tian,  

    下面的例子是使用windows 的 api:SHFileOperation, 它会直接调用到windows内核,会省去中间CLR这一层。

                string errorme="";
                FileOperateProxy.DeleteFile(@"D:\screenshot222.png", true, false, false, ref errorme);
                MessageBox.Show(errorme);
    
        public class FileOperateProxy
        {
           
            private struct SHFILEOPSTRUCT
            {
                public IntPtr hwnd;      
                public wFunc wFunc;      
                public string pFrom;    
                public string pTo;      
                public FILEOP_FLAGS fFlags;        
                public bool fAnyOperationsAborted;    
                public IntPtr hNameMappings;      
                public string lpszProgressTitle;   
            }
            private enum wFunc
            {
                FO_MOVE = 0x0001,  //移动文件
                FO_COPY = 0x0002,  //复制文件
                FO_DELETE = 0x0003, //删除文件,只是用pFrom
                FO_RENAME = 0x0004 //文件重命名
            }
            private enum FILEOP_FLAGS
            {
                FOF_MULTIDESTFILES = 0x0001,   
                FOF_CONFIRMMOUSE = 0x0002,
                FOF_SILENT = 0x0044,       
                FOF_RENAMEONCOLLISION = 0x0008,  
                FOF_NOCONFIRMATION = 0x10,    
                FOF_WANTMAPPINGHANDLE = 0x0020, 
                FOF_ALLOWUNDO = 0x40,      
                FOF_FILESONLY = 0x0080,      
                FOF_SIMPLEPROGRESS = 0x0100,   
                FOF_NOCONFIRMMKDIR = 0x0200,   
                FOF_NOERRORUI = 0x0400,      
                FOF_NOCOPYSECURITYATTRIBS = 0x0800,   
                FOF_NORECURSION = 0x1000     
            }
            
            [DllImport("shell32.dll")]
            private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
           
            /// <summary>
            /// 删除单个文件。
            /// </summary>
            /// <param name="fileName">删除的文件名</param>
            /// <param name="toRecycle">指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除</param>
            /// <param name="showDialog">指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框</param>
            /// <param name="showProgress">指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效</param>
            /// <param name="errorMsg">反馈错误消息的字符串</param>
            /// <returns>操作执行结果标识,删除文件成功返回0,否则,返回错误代码</returns>
            public static int DeleteFile(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg)
            {
                try
                {
                    string fName = GetFullName(fileName);
                    return ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg);
                }
                catch (Exception ex)
                {
                    errorMsg = ex.Message;
                    return -200;
                }
            }
    
    
           
            private static int ToDelete(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg)
            {
                SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT();
                lpFileOp.wFunc = wFunc.FO_DELETE;
                lpFileOp.pFrom = fileName + "\0";    //将文件名以结尾字符"\0"结束
                lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI;
                if (toRecycle)
                    lpFileOp.fFlags |= FILEOP_FLAGS.FOF_ALLOWUNDO; //设定删除到回收站
                if (!showDialog)
                    lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION;   //设定不显示提示对话框
                if (!showProgress)
                    lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT;   //设定不显示进度对话框
                lpFileOp.fAnyOperationsAborted = true;
                int n = SHFileOperation(ref lpFileOp);
                if (n == 0)
                    return 0;
                string tmp = GetErrorString(n);
                //.av 文件正常删除了但也提示 402 错误,不知道为什么。屏蔽之。
                if ((fileName.ToLower().EndsWith(".av") && n.ToString("X") == "402"))
                    return 0;
                errorMsg = string.Format("{0}({1})", tmp, fileName);
                return n;
            }
    
            /// 获取一个文件的全名
            /// </summary>
            /// <param name="fileName">文件名</param>
            /// <returns>返回生成文件的完整路径名</returns>
            private static string GetFullName(string fileName)
            {
                FileInfo fi = new FileInfo(fileName);
                return fi.FullName;
            }
    
            /// <summary>
            /// 解释错误代码
            /// </summary>
            /// <param name="n">代码号</param>
            /// <returns>返回关于错误代码的文字描述</returns>
            private static string GetErrorString(int n)
            {
                if (n == 0) return "Delete successful";
                switch (n)
                {
                    case 2:
                        return "系统找不到指定的文件。";
                    case 7:
                        return "存储控制块被销毁。您是否选择的“取消”操作?";
                    case 113:
                        return "文件已存在!";
                    case 115:
                        return "重命名文件操作,原始文件和目标文件必须具有相同的路径名。不能使用相对路径。";
                    case 117:
                        return "I/O控制错误";
                    case 123:
                        return "指定了重复的文件名";
                    case 116:
                        return "The source is a root directory, which cannot be moved or renamed.";
                    case 118:
                        return "Security settings denied access to the source.";
                    case 124:
                        return "The path in the source or destination or both was invalid.";
                    case 65536:
                        return "An unspecified error occurred on the destination.";
                    case 1026:
                        return "在试图移动或拷贝一个不存在的文件.";
                    case 1223:
                        return "操作被取消!";
                    default:
                        return "未识别的错误代码:" + n;
                }
            }
    
    
        }
    

    Best Regards

    Yong Lu

     

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年5月7日 2:24
  • 放到WCF服务下还是不行。文件被直接删掉了,回收站里面没有,返回值是2
    2019年5月7日 8:52
  • 到底是WPF还是WCF?这个是WPF版块,所以之前都是假定你的问题是基于WPF的。另外你删除的是什么文件?是怎么删除的?能不能把代码贴上来。如果是基于WCF的,也可以让版主把帖子转移到WCF版块去。
    2019年5月7日 8:58
  • WCF服务,麻烦转过去吧,代码就是楼上贴的代码。
    2019年5月7日 9:07
  • 回收站是资源管理器API的一部分,资源管理器的API都是不支持在服务下运行的。

    你可以写个代理程序在用户登录的时候运行,在代理程序里删除文件。



    Visual C++ MVP

    2019年5月7日 16:30
    版主