I'm trying to build a simple archiving program. We have files scattered throughout the system so part of the routine checks to see if a shortcut was put into the system and if so, to fetch all of the files from where the shortcut points to. It was all working fine a few weeks ago, but when I applied some visual studio updates it seems to have ceased working.
var downloadFilePath = Path.Combine(storFolder, caseEntity.ID, caseDocs.FileName);
if (downloadFilePath.Contains(".lnk"))
{
try
{
Console.WriteLine("Link Found. Now Processing.");
DirectoryInfo source = new DirectoryInfo(GetShortcutTargetFile(downloadFilePath));
DirectoryInfo target = new DirectoryInfo(storFolder + "\\" + nuFolder);
CopyFilesRecursively(source, target);
}
catch { Console.WriteLine("Bad link, no documents found."); }
}
Using break points it looks like the problem is in the "DirectoryInfo source..." line but I can't figure out why it's failing.
This is the GetShortcutTargetFile function.
public static string GetShortcutTargetFile(string shortcutFilename)
{
string pathOnly = Path.GetDirectoryName(shortcutFilename);
string filenameOnly = Path.GetFileName(shortcutFilename);
Shell shell = new Shell();
Folder folder = shell.NameSpace(pathOnly);
FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null)
{
ShellLinkObject link = (ShellLinkObject)folderItem.GetLink;
return link.Path;
}
return string.Empty; // not found
}
Related
I have an app in which the user needs to access certain files in a user set and selected folder.
The folder and files paths need to be easily accessed (short simple path).
I use the Properties Settings to hold the Folder and File paths, but for some reason each time I re-start the program the Folder and File paths are lost.
I have followed and checked the program and all seems to be OK (except something I am missing, apparently).
I attach here the program snippet in two parts: The search for path and the setting in case path / file not found. (removed exception handling to save on lines)
public Main() //part of Main, stripped off exception handling)
{
//..........
dataFolder = Properties.Settings.Default.dataFolder;
if (!Directory.Exists(dataFolder))
{
SetDataFolder();
}
configFile = Properties.Settings.Default.configFile;
if (!File.Exists(configFile))
{
SetConfigFile();
}
dataFile = Properties.Settings.Default.dataFile;
if (!File.Exists(dataFile))
{
SetDataFile();
}
loadParamsFromFile(configFile); //Load the previously saved controls.
public String SetDataFolder()
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
DialogResult folder = dialog.ShowDialog();
if (folder == DialogResult.OK)
{
dataFolder = dialog.SelectedPath;
Directory.CreateDirectory(dataFolder);
dataFolder = Path.GetFullPath(dataFolder);
Properties.Settings.Default.dataFolder = dataFolder;
Properties.Settings.Default.Save();
return dataFolder;
}
else return null;
}
private string SetDataFile()
{
dataFile = $"{dataFolder}\\{textBoxSampleID.Text.Replace("/r", "").Trim()}.txt";
File.Create(dataFile).Close();
Properties.Settings.Default.dataFile = dataFile;
Properties.Settings.Default.Save();
return dataFile;
}
private string SetConfigFile()
{
configFile = $"{dataFolder}\\electroplating.cfg";
File.Create(configFile).Close();
Properties.Settings.Default.configFile = configFile;
Properties.Settings.Default.Save();
return configFile;
}
Check out this question:
How to change application settings (Settings) while app is open?
I would suggest using Path.Combine() for the construction of the file paths.
If it still doesn't work, you could also try using the registry for storing the values.
string dataFilePath = Path.Combine(dataFolder, textBoxSampleID.Text.Replace("/r", "").Trim());
RegistryKey key = Registry.LocalMachine.CreateSubKey(#"SOFTWARE\Company");
if (key != null)
{
key.SetValue("dataFilePath", dataFilePath);
}
You could then use string dataFilePath = (string)key.GetValue("dataFilePath") to get the value out of the registry.
I have a Visual Studio solution with the following structure:
- root
- src
- project01
- project02
- config
- application.config
- database.dacpac
Now, assuming I am executing a code from the path:
C:\DEV\root\project01\bin\release\project01.exe
How can I find the first occurrence of the file "application.config" for example?
I know that I can start with this:
public string GetExecutingDirectory(){
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
And use it in the following way:
var executingDirectory = GetExecutingDirectory();
But now, how can I traverse the Root Tree back and forward until I find the file I am looking for?
I tried this code but it doesn't find anything:
var path = Directory
.GetFiles(executingDirectory,
"**/application.config",
System.IO.SearchOption.AllDirectories);
I need it because I am running Integration Tests from different paths and they need these files which can be in a different location of the solution tree depending on the DEV machine configuration so I need to use the "pattern" because the structure can be different from PC to PC.
You can do like this:
static string FindConfig()
{
string appFolder = Path.GetDirectoryName(#"C:\DEV\root\project01\bin\release\project01.exe");
string configPath = null;
while (true)
{
Console.WriteLine(appFolder);
string[] files = Directory.GetFiles(appFolder, "*application.config", SearchOption.AllDirectories);
foreach (var file in files)
{
if (file.ToLower().EndsWith(#"\application.config"))
{
return file;
}
}
appFolder = Path.GetDirectoryName(appFolder);
if (appFolder.Length < 4) // "C:\" don't search root drive
{
break;
}
}
return configPath;
}
I'm trying to do a recursive loop through "Start Menu" folder using following code:
Function(string pathFolder) {
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder folderObj = shell.NameSpace(pathFolder);
foreach ( Shell32.FolderItem2 item in objFolder.Items() ) {
string typeItem = folderObj.GetDetailsOf(item, 2);
if ( typeItem == "File folder" ) {
string folderName = folderObj.GetDetailsOf(item, 0);
Function(pathFolder + "\\" + folderName);
} else {
// do smomething...
}
}
The problem is Shell.Namespace works fine for some folders, not all. For those not-working folders, Shell.Namespace return null even these folders do exist.
What's wrong with my code?
Why are not you using System.IO namespace classes? I think it has more advanced API. For your case it maybe security issues.
I am trying to get a list of files in a folder on the filesystem in my .net web app. When I run the app, I am getting an error that says that the directory "is not a valid virtual path". How do I get this to return files, that are in my WebApp's directory (they are located in {webapp root}\docs\custFiles).
try
{
List<string> custFiles = new List<string>();
StringBuilder dir = new StringBuilder(#"~\docs\custFiles\");
dir.Append(custNo + #"\");
string directory = HttpContext.Current.Server.MapPath(dir.ToString());
bool IsExists = System.IO.Directory.Exists(directory);
if (!IsExists)
{
string[] fileList = Directory.GetFiles(directory);
custFiles = (fileList.ToList());
}
return custFiles;
}
catch (Exception ex)
{
throw ex;
}
The problem is this line:
bool IsExists = System.IO.Directory.Exists(Server.MapPath(directory));
As you've already built the directory name here:
string directory = HttpContext.Current.Server.MapPath(dir.ToString());
You can just use the Exists call without Server.MapPath:
bool IsExists = System.IO.Directory.Exists(directory);
Well, It seems problem with virtual path you are passing. Instead that try this.
String directory=Server.MapPath("~/docs/custFiles");
if(System.IO.Directory.Exists(directory))
{
//do your coding..
}
I've perhaps done something marginally stupid, but can't see what it is!!
string pegasusKey = #"HKEY_LOCAL_MACHINE\SOFTWARE\Pegasus\";
string opera2ServerPath = #"Server VFP\";
string opera3ServerPath = #"O3 Client VFP\";
string opera2InstallationPath = null;
string opera3InstallationPath = null;
//Gets the opera Installtion paths and reads to the string opera*InstallationPath
opera2InstallationPath = (string)Registry.GetValue(pegasusKey + opera2ServerPath + "System", "PathToServerDynamic", null);
opera3InstallationPath = (string)Registry.GetValue(pegasusKey + opera3ServerPath + "System", "PathToServerDynamic", null);
string Filesource = null;
string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string File in FileList)
Filesource = File;
label.Text = Filesource;
if (System.IO.Directory.Exists(opera3InstallationPath))
{
System.IO.File.Copy(Filesource, opera3InstallationPath);
MessageBox.Show("File Copied from" + Filesource + "\n to" + opera3InstallationPath);
}
else
{
MessageBox.Show("Directory Doesn't Exist");
}
The user drags the file onto the window, I then get the installation path of an application which is then used as the destination for the source file.. When the application is runs, it throws the error directory not found. But surely if the directory doesn't exists is should step into the else statement? a simple application that is becoming a headache!!
Your Filesource must be invalid. Here's what I suggest:
Step your code, put a break point on first line of the if(Directory.Exists(...)) code block.
Examine Filesource by adding it to the watch window, check if it is what you expect
Open the "Immediate Window" Type File.Exists(Filesource) and check result (should be true). Or.. Directory.Exists(Path.GetDirectory(Filesource))
Also, I'm almost certain you have a logic error in this portion of your code.. (You are assigning a variable in a loop over and over again, did you mean to append it? This doesn't make sense).
string Filesource = null;
string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string File in FileList)
Filesource = File;
label.Text = Filesource;