I wonder if it was possible to prevent or at least detect if my application is being used from a network drive instead of a local folder/drive.
I wish to inform my user that he has to copy the sources and run them locally because of heavy performance pitfalls.
Get the path to where your executable has been executed from, get the root, then find out if it is a network drive.
var root = Path.GetPathRoot(Assembly.GetEntryAssembly().Location)
var driveInfo = new DriveInfo(root));
if (driveInfo.DriveType == DriveType.Network) {
// Alert that this will be slow.
}
Note that you should read the question I linked (How can I get the application's path in a .NET console application?), as there is potentially a bit more to it than the code above, depending on your exact scenario.
to prevent ArgumentException in case GetPathRoot returns \\Share\myshare
DriveInfo driveInfo = null;
try
{
driveInfo = new DriveInfo(Path.GetPathRoot(Assembly.GetEntryAssembly().Location));
}
catch (Exception)
{
}
if (driveInfo == null || driveInfo.DriveType == DriveType.Network)
{
//not allowed
}
Related
I am trying to read the boot sector of a cd drive so that I can extract its contents. Unfortunately, no matter what I do I can't seem to get it working. I have tried reading the directory as a file but get access denied. Tried reading right from /dev/disk# and got locked.
I have also tried checking and changing permissions, but nothing.
In Windows, I would use CreateFile & ReadFile from kernel32. I just am not sure what the macOS equivalent would be.
public static List<DriveInfo> GetDrives() => DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveType == DriveType.CDRom).ToList();
public static ReadDrives()
{
var drives = GetDrives()
foreach(var drive in drives)
{
var root = drive.RootDirectory.FullName;
using (var fp = File.OpenRead(#"/Volumes/Flash - Copy/"))
{
//extract boot here
}
}
}
This is not the best answer, but this works for me, no sudo needed.
It is at least a solution for now.
var command = $"-c \"umount {inputDisc} && dd if={inputDisc} of={outputfile} bs=32k count=1 && mount {inputDisc}\"";
Process.Start("/bin/bash", command);
I have a UWP application which perform to capture and process images from a camera. This project leverage Microsoft Cognitive Services Face Recognition API and I'm exploring the application's existing functionality for awhile now. My goal is that when the image of a person is identified by the camera (through Face Recognition API service), I want to show the associated image of that person.
With that, the images are captured and stored in a local directory of my machine. I want to retrieve the image file and render it on the screen once the person is identified.
The code below shows the async Task method ProcessCameraCapture
private async Task ProcessCameraCapture(ImageAnalyzer e)
{
if (e == null)
{
this.UpdateUIForNoFacesDetected();
this.isProcessingPhoto = false;
return;
}
DateTime start = DateTime.Now;
await e.DetectFacesAsync();
if (e.DetectedFaces.Any())
{
string names;
await e.IdentifyFacesAsync();
this.greetingTextBlock.Text = this.GetGreettingFromFaces(e, out names);
if (e.IdentifiedPersons.Any())
{
this.greetingTextBlock.Foreground = new SolidColorBrush(Windows.UI.Colors.GreenYellow);
this.greetingSymbol.Foreground = new SolidColorBrush(Windows.UI.Colors.GreenYellow);
this.greetingSymbol.Symbol = Symbol.Comment;
GetSavedFilePhoto(names);
}
else
{
this.greetingTextBlock.Foreground = new SolidColorBrush(Windows.UI.Colors.Yellow);
this.greetingSymbol.Foreground = new SolidColorBrush(Windows.UI.Colors.Yellow);
this.greetingSymbol.Symbol = Symbol.View;
}
}
else
{
this.UpdateUIForNoFacesDetected();
}
TimeSpan latency = DateTime.Now - start;
this.faceLantencyDebugText.Text = string.Format("Face API latency: {0}ms", (int)latency.TotalMilliseconds);
this.isProcessingPhoto = false;
}
In GetSavedFilePhoto, I passed the string names argument once the person is identified.
Code below for the GetSavedFilePhoto method
private void GetSavedFilePhoto(string personName)
{
if (string.IsNullOrWhiteSpace(personName)) return;
var directoryPath = #"D:\PersonImages";
var directories = Directory.GetDirectories(directoryPath);
var filePaths = Directory.GetFiles(directoryPath, "*.jpg", SearchOption.AllDirectories);
}
However, in GetSavedFilePhoto method the variable directories returned an empty string of array when using directoryPath string variable. Directory "D:\PersonImages" is a valid and existing folder in my machine and, it contains subfolders with images inside. I also tried Directory.GetFiles to retrieve the jpg images but still returned an empty string.
I think it should work because I have used Directory class several times but not inside an asyncTask method. Does using async caused the files not returned when using I/O operation?
Sorry for this stupid question, but I really don't understand.
Any help is greatly appreciated.
Using Directory.GetFiles or Directory.GetDirectories method can get the folder/file in the local folder of the Application by the following code. But it could not open D:\.
var directories = Directory.GetDirectories(ApplicationData.Current.LocalFolder.Path);
In UWP app you can only access two locations at default (local folder and install folder), others need capabilities setting or file open picker.Details please reference file access permission.
If you need access to all files in D:\, the user must manually pick the D:\ drive using the FolderPicker, then you have permissions to access to files in this drive.
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.ComputerFolder;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
// Application now has read/write access to the picked file
}
else
{
//do some stuff
}
trying to write a small windows application for my company. the part i am stuck at the moment is trying to search the computer for ".myox" files (or say any file type). Below pasted is the code i have worked out. I am an amateur programmer trying to get started with coding. The issue am having at the moment with the code below is its skipping almost all locations on the computer with the exception coming up as "access denied". I have run the VS as admin, and i am an admin on the computer as well. Not sure what i am missing, but if someone can point me in the right direction, that would be amazing.
private void FindAllFiles()
{
int drvCount;
int drvSearchCount = 0;
DriveInfo[] allDrives = DriveInfo.GetDrives();
drvCount = allDrives.Count();
foreach (DriveInfo dr in allDrives)
{
lbAllFiles.Items.Clear();
drvSearchCount++;
//removable drives
if (!dr.IsReady)
break;
foreach (string dir in Directory.GetDirectories(dr.ToString()))
{
try
{
foreach (string files in Directory.GetFiles(dir, "*.myox"))
{
lbAllFiles.Items.Add(files);
}
}
catch (Exception Error)
{
}
}
if (drvSearchCount == drvCount)
break;
}
MessageBox.Show("Done searching your computer");
}
Thanks in Advance.
-Manu
I see few "potential" issues and will list them below.
First is that you're doing this on main ( UI ) thread which will block whole application giving you no feedback about current state. You can use Thread to get rid of this problem. Outcome from this operation will produce another issue which is accessing lbAllFiles because ( as i think ) it's part of the UI. You can easily get rid of this problem making a List<string> that can be filled during FindAllFiles operation and then assigned into lbAllFiles.Items.
Second issue is :
foreach (string files in Directory.GetFiles(dir, "*.myox"))
{
lbAllFiles.Items.Add(files);
}
Directory.GetFiles(...) will return only the files that are matching your pattern parameter so you can simply do :
var files = Directory.GetFiles(dir, "*.myox");
if ( files != null && files.Length > 0 )
lblAllFiles.Items.AddRange(files);
And finaly to get ( or check ) permission you can Demand() permissions as I've posted in the comment :
foreach (string dir in Directory.GetDirectories(dr.ToString()))
{
FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, dir);
try
{
permission.Demand();
var files = Directory.GetFiles(dir, "*.myox");
if ( files != null && files.Length > 0 )
lblAllFiles.Items.AddRange(files);
}
catch (Exception Error)
{
}
}
Let me know if that helped you. If not I'll try to update my answer with another solution.
One thing i noticed in your code, is that you're not navigating through ALL directories and sub-directories. For that, where you call the GetDirectories function, not only send the path, but use the enumerator Alldirectories:
foreach (string dir in Directory.GetDirectories(dr.ToString(),System.IO.SearchOption.AllDirectories))
I need to get the user directory from within a C# windows service...
...like C:\Users\myusername\
Ideally, I'd like to have the roaming path...
...like C:\Users\myusername\AppData\Roaming\
When I used the following in a console program I got the correct user directory...
System.Environment.GetEnvironmentVariable("USERPROFILE");
...but when I use that same variable in a service, I get...
C:\WINDOWS\system32\config\systemprofile
How can I get the user folder and maybe even the roaming folder location from a service?
Thanks in advance.
I have searched for getting the profile path of user from Windows service. I have found this question, which does not include a way to do it. As I have found the solution, partly based on a comment by Xavier J on his answer, I have decided to post it here for others.
Following is a piece of code to do that. I have tested it on few systems, and it should work on different OSes ranging from Windows XP to Windows 10 1903.
//You can either provide User name or SID
public string GetUserProfilePath(string userName, string userSID = null)
{
try
{
if (userSID == null)
{
userSID = GetUserSID(userName);
}
var keyPath = #"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" + userSID;
var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(keyPath);
if (key == null)
{
//handle error
return null;
}
var profilePath = key.GetValue("ProfileImagePath") as string;
return profilePath;
}
catch
{
//handle exception
return null;
}
}
public string GetUserSID(string userName)
{
try
{
NTAccount f = new NTAccount(userName);
SecurityIdentifier s = (SecurityIdentifier)f.Translate(typeof(SecurityIdentifier));
return s.ToString();
}
catch
{
return null;
}
}
First, you'll want to use Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
Environment.SpecialFolder.ApplicationData is for roaming profiles.
Find all SpecialFolder enumeration values here: https://msdn.microsoft.com/en-us/library/system.environment.specialfolder(v=vs.110).aspx
As others have noted, the Service will run under the account LocalSystem/LocalService/NetworkService, depending on configuration: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686005(v=vs.85).aspx
A service doesn't log on like a user, unless the service is configured to use a specific user's profile. So it's not going to point to "user" folders.
When i search files through a string in my local drives it shows the following error and it stops to search further.The reason is some of the windows files are used by the OS when the search is in progress.How to overcome this.
The process cannot access the file 'C:\hiberfil.sys'(Hibernate Files) because it is being used by another process.
TextReader rff = null;
rff = new StreamReader(fi.FullName);
try
{
String lne1 = rff.ReadToEnd();
if (lne1.IndexOf(txt) >= 0)
{
z = fi.FullName;
list22.Add(fi.FullName);
You should narrow down your search wildcard to avoid hitting system or locked files or you will always get this exception. In .NET 4.0 you could use the EnumerateFiles method which will perform the search lazily and you could catch the exception.
c:\hiberfil.sys is a system file that is locked against reading. You won't be able to read it because of that. There is no call you can do in c# to determine if a file is locked before you attempt to open it, so put Try/Catch blocks around your attempt to open it and if it throws an exception, just go on to the next file.
TextReader rff = null;
try
{
rff = new StreamReader(fi.FullName);
String lne1 = rff.ReadToEnd();
if (lne1.IndexOf(txt) >= 0)
{
z = fi.FullName;
list22.Add(fi.FullName);