I want to delete a file stored in an USB flashdrive (actually an android device's sd card).
I ask the user to point the app's folder inside the sd card, and i hold a Shell32.Folder
object pointing to it.
I can iterate between the files (FolderItem
objects), but how can i delete a file using Shell32
classes?
Usual File.Delete(filePath)
does not work, since the FolderItem.Path
is a BSTR data type, so maybe the key is to convert from one type to another, but i couldn't find a way to do this.
Any ideas?
EDIT 1:
FolderItem.Path
data:
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp>-p5100#7&392be4e4&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{10001,SECZ9519043CHOHB,12530364416}\{015C008D-013D-0145-D300-D300CB009500}\{015C00EE-013D-0145-0201-37012C010901}\{025901D2-029D-020F-DE01-FE010D02A601}"
This is not a valid path for File.Delete
. Any ideas on how to convert that?
EDIT 2:
Method that opens the browse folder window, so the user can point out the app directory, inside his android device's SD card, so i can iterate with folders and files, and sync some data with the server. Done this way due to problems between Win8 and 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 });
}
Using the method above, to get the Folder:
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
Folder androidPath = BrowseForFolder(windowHandle.ToInt32(), "App's data folder", 0, 0);
I create and copy a file into the app's 'data' folder, so the device can recognize a syncing action, tell the user, and close the app:
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;
}
}
}
After the sync, i want to delete the file, so the app can function normally:
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;
}
}
As mentioned in EDIT 1, file.Path
of the file i want to delete, has the following format:
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp>-p5100#7&392be4e4&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{10001,SECZ9519043CHOHB,12530364416}\{015C008D-013D-0145-D300-D300CB009500}\{015C00EE-013D-0145-0201-37012C010901}\{025901D2-029D-020F-DE01-FE010D02A601}"
EDIT 3:
As suggested here, i tried using P/Invoke to delete the file, with no success.
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteFile(string lpFileName);
Calling the method:
foreach (FolderItem file in dataFolder.Items())
{
if (file.Name.Contains(flagFileName))
{
// ...
bool deleted = DeleteFile(file.Path);
// ...
}
}
The method returns false, and the file is not deleted. I looked in the Event Viewer for a clue about what happened, but found nothing.