C# 删除文件夹项
我想删除存储在USB闪存驱动器(实际上是android设备的sd卡)中的文件 我要求用户将应用程序的文件夹指向sd卡中,我拿着一个指向它的C# 删除文件夹项,c#,bstr,shell32,C#,Bstr,Shell32,我想删除存储在USB闪存驱动器(实际上是android设备的sd卡)中的文件 我要求用户将应用程序的文件夹指向sd卡中,我拿着一个指向它的Shell32.folder对象 我可以在文件(FolderItem对象)之间进行迭代,但如何使用Shell32类删除文件 通常的File.Delete(filePath)不起作用,因为FolderItem.Path是一种BSTR数据类型,所以可能关键是从一种类型转换为另一种类型,但我找不到一种方法 有什么想法吗 编辑1: FolderItem.Path数据:
Shell32.folder
对象
我可以在文件(FolderItem
对象)之间进行迭代,但如何使用Shell32
类删除文件
通常的File.Delete(filePath)
不起作用,因为FolderItem.Path
是一种BSTR数据类型,所以可能关键是从一种类型转换为另一种类型,但我找不到一种方法
有什么想法吗
编辑1:
FolderItem.Path
数据:
以下几::::{20 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 025901D2-029D-020F-DE01-FE010D02A601}”
这不是文件的有效路径。请删除。有没有办法把它转换成其他的
编辑2:
方法打开“浏览文件夹”窗口,这样用户就可以指出android设备SD卡中的应用程序目录,这样我就可以迭代文件夹和文件,并与服务器同步一些数据。由于Win8和Shell32之间存在问题,因此采用这种方式:
public Shell32.Folder GetShell32NameSpace(Object folder)
{
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellAppType);
return (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
}
使用上述方法,要获取文件夹:
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
Folder androidPath = BrowseForFolder(windowHandle.ToInt32(), "App's data folder", 0, 0);
我创建一个文件并将其复制到应用程序的“数据”文件夹中,以便设备能够识别同步操作,告知用户并关闭应用程序:
byte[] data = new UTF8Encoding(true).GetBytes("sync_cable");
if (androidPath != null)
{
foreach (FolderItem dir in androidPath.Items())
{
if (dir.IsFolder && dir.Name == "data")
{
Folder dataFolder = GetShell32NameSpace(dir.Path);
if (dataFolder != null)
{
string tempPath = Path.GetTempPath();
string path = Path.Combine(tempPath, flagFileName);
File.WriteAllBytes(path, data);
Folder localPath = GetShell32NameSpace(tempPath);
if (localPath != null)
{
foreach (FolderItem file in localPath.Items())
{
if (file.Name.Contains(flagFileName))
{
dataFolder.CopyHere(file);
break;
}
}
}
}
break;
}
}
}
同步后,我想删除文件,这样应用程序才能正常运行:
foreach (FolderItem file in dataFolder.Items())
{
if (file.Name.Contains(flagFileName))
{
// THIS THROWS AN 'INVALID PATH' EXCEPTION
// FileInfo fi = new FileInfo(file.Path);
// fi.Delete();
// THIS ALSO THROWS AN 'INVALID PATH' EXCEPTION
// File.Delete(file.Path);
break;
}
}
如编辑1中所述,我要删除的文件的file.Path
具有以下格式:
以下几::::{20 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 025901D2-029D-020F-DE01-FE010D02A601}”
编辑3:
正如这里所建议的,我尝试使用p/Invoke删除该文件,但没有成功
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteFile(string lpFileName);
调用该方法:
foreach (FolderItem file in dataFolder.Items())
{
if (file.Name.Contains(flagFileName))
{
// ...
bool deleted = DeleteFile(file.Path);
// ...
}
}
该方法返回false,并且不会删除该文件。我在事件查看器中查找发生的事情的线索,但没有找到任何线索。路径中类似“\?\”的部分告诉您这是一条很长的路径。遗憾的是,CLR无法处理长路径(它被限制为MAX_PATH=260)。我相信你可以使用WinAPI的DeleteFile来完成你想要的
使用PInvoke,您将一切就绪
guid前缀(:{20D04FE0-3AEA-1069-A2D8-08002B30309D})是MyComputer的标准连接点(请参阅)
我怀疑无法使用shell API DeleteFile之类的方法删除该文件,因为它不在文件系统中(您可以使用FolderItem.IsFileSystem进行检查),因为android设备是使用MTP连接的
我已经能够使用FolderItem.InvokeVerb(“删除”)删除这些文件。这将生成一个确认对话框,可以使用某些版本的SendKeys(例如免费软件Nirsoft的Nircmd.exe)取消该对话框。以下是VBA示例:
Private Sub SampleDelete()
Const sFolder = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_054c&pid_04cb#10fbd475671683#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{10001,00000000000000000000000005671683,7513636864}\{00000007-0000-0000-0000-000000000000}\{000057F1-0000-0000-66A5-884D99020600}"
Const sFileName = "test.txt"
' requires reference to Shell32.dll
Dim oShell As New Shell32.Shell
Dim oFolder As Shell32.Folder
Dim oFile As Shell32.FolderItem
Set oFolder = oShell.Namespace(sFolder)
If Not oFolder Is Nothing Then
Set oFile = oFolder.ParseName(sFileName)
If Not oFile Is Nothing Then
Debug.Print "File system? " & oFile.IsFileSystem
' dismiss the confirmation dialog
SendKeys "~"
' Alternatively use an external function, like this freeware utility
' Shell "nircmd.exe sendkey enter press", vbHide
oFile.InvokeVerb "Delete"
Else
Debug.Print "File not found"
End If
Else
Debug.Print "Folder not found"
End If
Set oShell = Nothing
Set oFolder = Nothing
Set oFile = Nothing
End Sub
这不是它的工作方式。添加对shell32.dll的引用时,使用CLR中内置的COM互操作。它会自动在BSTR和System.StringThank@HansPassant之间来回转换,我明白了。因此,FolderItem.Path已经是一个托管字符串,但其内容的格式与File.Delete不同。在这种情况下,如何转换此路径?或者甚至使用shell删除文件?如何ToString()
?似乎你应该从中得到一个字符串。@Hogan,数据已经是一个字符串了,我编辑了这个问题以便更清楚地了解我要完成的任务。你试过路径吗?@B.K.奇怪。我做了一个快速搜索,找到了这个博客,测试了结果,它们在Win8上对我有效可能是导致问题的::{}前缀。