Can't get directory from external device - c#

I'm trying to get the items from within a folder on an Android phone.
However the FolderBrowserDialog won't let me select a folder from within in the phone. The path looks like this This PC\Xperia Z3 Compact\SD Card\Music
To select a folder I'm currently using:
private void button_Click(object sender, EventArgs e)
{
System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
UserFolderLocation = dlg.SelectedPath;
}
else { }
}
Then when searching the folder for its contents I use:
try
{
folderItems = Directory.GetFiles(directory).Select(f => Path.GetFileNameWithoutExtension(f)).ToArray();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
If I insert the path This PC\Xperia Z3 Compact\SD Card\Music as a variable then search it, it throws a System.IO.DirectoryNotFoundException.
How do I select and use a path that doesn't begin with c:, d: etc?

In the end I ended up using the shell32 library. It has the ability to handle portable devices (That both include and don't include the drive letters).
Include the reference for shell32.dll
and include the library:
using Shell32;
Then instead of using the FolderBrowserDialog I used the use the shell browse for folder. Which returns a strange path for a folder on a phone, for the phone I used to test the path looked like this:
::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&fee689d&3&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{20002,SECZ9519043CHOHB01,63829639168}\{013C00D0-011B-0130-3A01-380113012901}
public int Hwnd { get; private set; }
private void button3_Click(object sender, EventArgs e)
{
Shell shell = new Shell();
Folder folder = shell.BrowseForFolder((int)Hwnd, "Choose Folder", 0, 0);
if (folder == null)
{
// User cancelled
}
else
{
FolderItem fi = (folder as Folder3).Self;
UserFolderLocation = fi.Path;
}
}
Then to select search the folder for its contents:
try
{
Folder dir = shell.NameSpace(directory);
List<string> list = new List<string>();
foreach (FolderItem curr in dir.Items())
{
list.Add(curr.Name);
}
folderItems = list.ToArray();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}

"This PC" is only there for the eyes of the user - internally it is not used at all. You can see for yourself by applying the first marked setting in Windows Explorer
Additionally Windows assigns a drive letter to every local device - it just doesn't show it by default. (use the second marked setting to check)
So in reality you have to use (assuming you phone was assigned Drive F:) something like F:\SD Card\Music\.
Possibly related: Get List Of Connected USB Devices about the ability to find a device without knowing the assigned drive letter.

Related

Unable to write file in using cacls.exe

For installation using .NET, I wish to give write permission to a particular file in the folder using cacls.exe, so I have referred How to give Read/Write permissions to a Folder during installation using .NET and I have used the code from Setting File or Directory permissions ACE entries with .NET using CACLS.EXE.
After installation, on form load, I could read the file file.txt which is located at C:\Program Files\MyCompany\MyProduct , with below code:
private void Form1_Load(object sender, EventArgs e)
{
//Some code
DirectoryPermission dp = new
DirectoryPermission(filename, "Everyone", "F");
dp.SetAce();
foffset = read_file();
}
string filename = "file.txt";
private double read_file()
{
double value = 0;
try
{
value = Double.Parse(System.IO.File.ReadAllText(#filename));
return value;
}
catch
{
System.IO.File.WriteAllText(#filename, value.ToString());
return 0;
}
}
But on a button click I couldn't write the file with new value, so I wrote the below code and did installation, still the problem persist:
private void button1_Click(object sender, EventArgs e)
{
try{
DirectoryPermission dp = new
DirectoryPermission(filename , "Everyone", "F");
dp.SetAce();
System.IO.File.WriteAllText(#filename , offset.ToString());
}
catch
{}
}
I'm giving full control to all the users, but I'm not able to write the file. and I'm getting this error
Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.dll
Please help me in this.

UWP Parse folder from absolute or relative path

I want to parse a folder that the user can choose.
But if I understand, absolute paths are not allowed in UWP because the disks are not the same following the media (xbox, windows phone, windows desktop, ...) ?
So, I have a class called Parser that can parse the path that the user picks but now, only the current folder can be parsed.
This doesn't work :
Parser parser = new Parser(#"C:\a\b\c");
parser.createTreeView(tree);
Help me please. Thank you in advance.
EDIT : This is my Parser class =>
public TreeViewItem Parse(DirectoryInfo directoryInfo)
{
try
{
var directoryNode = new TreeViewItem { Header = directoryInfo.Name };
Convention convention = new Convention();
foreach (var directory in directoryInfo.GetDirectories())
{
directoryNode.Items.Add(Parse(directory));
System.Diagnostics.Debug.WriteLine("test : " + directory.Name);
}
foreach (var file in directoryInfo.GetFiles())
{
if (file.Name.Contains(EConvention.INSTALL))
{
listFiles.Add(file.FullName);
}
TreeViewItem item = new TreeViewItem
{
Header = Path.GetFileNameWithoutExtension(file.FullName),
Tag = file.FullName
};
directoryNode.Items.Add(item);
}
return directoryNode;
}
catch (System.UnauthorizedAccessException e)
{
//MessageDialog dialog = new MessageDialog(""+e.Message);
dialogAsync(e.Message);
return new TreeViewItem();
}
}
public void CreateTreeView(TreeView tree)
{
DirectoryInfo dir = new DirectoryInfo(pathToParse);
System.Diagnostics.Debug.WriteLine("dir exists ? "+dir.Exists);
if (dir.Exists)
{
System.Diagnostics.Debug.WriteLine("dir existe");
TreeViewItem root = new TreeViewItem() { Header = dir.Name };
root.Tag = dir;
tree.Items.Add(Parse(dir));
}
}
UWP apps do not have permission to access all files on the device. Apps can access certain file system locations by default. Apps can also access additional locations through the file picker, or by declaring capabilities. For more info, please see File access permissions
Although, we can use DirectoryInfo in UWP apps, but it can only work with the folders that UWP apps can access by default such as the install directory and local folder etc. Most types in the System.IO namespaces for UWP apps have the similar limitation. While dealing with files or folders in UWP, one important rule is Skip the path: stick to the StorageFile.
You can use a Folder​Picker to let the user choose a folder and then add it to your app's FutureAccessList or MostRecentlyUsedList to keep track of it. You can learn more about using these lists in How to track recently-used files and folders. After this, you will be able to retrieve the StorageFolder from FutureAccessList or MostRecentlyUsedList whenever you want to use it.
Once you have the StorageFolder, you can then use GetFilesAsync() or GetFoldersAsync() method in your Parse instead of DirectoryInfo.GetDirectories or DirectoryInfo.GetFiles method.

winrt how to get files list from device using c#

I need get a list of all files in device (phone or PC) in my universal app. In wpf I did somesing like that:
class Collection {
private StringCollection seachResults;
//find all mp3 files in local storage
private void ScanDrives() {
seachResults.Clear();
string[] drives = Environment.GetLogicalDrives();
foreach (string dr in drives) {
DriveInfo di = new DriveInfo(dr);
if (!di.IsReady) {
//skip if drive not ready
continue;
}
DirectoryInfo rootDir = di.RootDirectory;
WalkDirectoryTree(rootDir);
}
}
private void WalkDirectoryTree(DirectoryInfo root) {
FileInfo[] files = null;
DirectoryInfo[] subDirs = null;
try {
files = root.GetFiles("*.mp3");
} catch (UnauthorizedAccessException e) {
} catch (DirectoryNotFoundException e) {
}
if (files != null) {
foreach (FileInfo fileInfo in files) {
seachResults.Add(fileInfo.FullName);
}
subDirs = root.GetDirectories();
foreach (DirectoryInfo dirInfo in subDirs) {
WalkDirectoryTree(dirInfo);
}
}
}
}
But when I try to migrate this into winRT app I get a few errors like unknown type Drive and unexisted method Environment.GetLogicalDrives().
Can anyone say how do that in winRT?
You won’t find a method for getting all logical drives in a WinRT app; WinRT apps exist in a sandboxed environment and will only have access to their own isolated storage or known folders (such as music) if declared as a capability in the application manifest.
For example, to get access to the user’s music folder you can do this (don’t forget to declare the capability in the app manifest):
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
The only way to get access to any other part of the file system is if the user specifically grants access via a file picker:
var folderPicker = new FolderPicker();
var folder = await folderPicker.PickSingleFolderAsync();
Have you tried System.IO.Directory.GetLogicalDrives()?
I believe that Environment.GetLogicalDrives() only works for Win32/Win64. If I am not mistaken System.IO.Directory exists in mscorlib, and is widely available across Phone, RT, or Regular versions.
The MSDN reference:
https://msdn.microsoft.com/en-us/library/system.io.directory.getlogicaldrives%28v=vs.110%29.aspx

Add the list of messagebox to a resource file in c#

I've already wrote my code with my try catch and extra message box but now i have to put the message box into a resource file how can i do it?
This is my code:
public void btnUpload_Click(object sender, EventArgs e)
{
try
{
// in the filepath variable we are going to put the path file that we browsed.
filepath = txtPath.Text;
if (filepath == string.Empty)
{
MessageBox.Show("No file selected. Click browse and select your designated file.");
}
}
You can just add those messages as String in your main application Resource file using the designer (Resources.resx) and then access them using Properties namespace. Let's say you add this:
ErrorNoFile | "No file selected. Click browse and select your designated file."
You can just call it like so:
MessageBox.Show(Properties.Resources.ErrorNoFile);
And if you modify the entry name in the resource file, it will be automatically refactored, at least with VS2012 which is the one I'm using. Instanciating a ResourceManager is only good if you want to keep those messages in a separate resource, otherwise it looks like an overkill to me.
// Create a resource manager to retrieve resources.
ResourceManager rm = new ResourceManager("items", Assembly.GetExecutingAssembly());
// Retrieve the value of the string resource named "filepath".
// The resource manager will retrieve the value of the
// localized resource using the caller's current culture setting.
public void btnUpload_Click(object sender, EventArgs e)
{
try
{
// in the filepath variable we are going to put the path file that we browsed.
filepath = txtPath.Text;
if (filepath == string.Empty)
{
String str = rm.GetString("welcome");
MessageBox.Show(str);
}
}

Isolated storage in windows phone 7

I am trying to do a check on the isolated storage followed by some command along with it.
What i wanted was to check for directories name consisting "a*"
*If the directories exist* it will check if the diretory named after "a + today date" exist.
If it exist will show up a pop up message telling it does exist.
But if no directories consisting of "a*" is exist at all it will show a message of "Does not exist".
Below is my code:
Is able to check if the directories exist when there is a directory of "a*" is created.
But it does not work *when none of the directories "a" is created**.
How should i modify my code?
Code:
string[] fileNames;
string selectedFolderName;
private void gameBtn_Click(object sender, RoutedEventArgs e)
{
//MediaPlayer.Stop();
string currentDate = DateTime.Now.ToString("MMddyyyy");
string currentDateName = "a" + currentDate;
IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication();
fileNames = myStore.GetDirectoryNames("a*");
foreach (var name in fileNames)
{
if (fileNames.Contains(currentDateName))
{
selectedFolderName = currentDateName;
MessageBox.Show("Your schedule for today");
NavigationService.Navigate(new Uri("/DisplaySchedule.xaml?selectedFolderName=" + selectedFolderName, UriKind.Relative));
}
else
{
MessageBox.Show("No Schdule for today", "Schedule Reminder", MessageBoxButton.OK);
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
}
}
Your error is just a simple typo.
if (fileNames.Contains(currentDateName))
should be
if (name.Contains(currentDateName))
As for handling when there's no directory "a*", check if fileNames is empty.
if (fileNames.Length == 0) // no Directory 'a' was found, create it
{
// create code here
}

Categories

Resources