A DirectoryNotFound exception keeps happening for no apparent reason. The exception is thrown in:
public static string[] getKeywords(string filename)
{
string[] keywords = XElement.Load(filename).Elements("Keyword").Attributes("name").Select(n => n.Value).ToArray();
return keywords;
}
BUT it is called in this method:
public static void SyntaxHighlight(SyntaxHighlighter.SyntaxRichTextBox textbox, Language language)
{
switch (language)
{
case Language.Cmake:
textbox.Settings.Comment = "#";
string[] CmakeKeywords = getKeywords("APIs\\cmake.xml");
textbox.Settings.Keywords.AddRange(CmakeKeywords);
break;
case Language.CSharp:
textbox.Settings.Comment = "//";
string[] CSharpKeywords = getKeywords("APIs\\cs.xml");
textbox.Settings.Keywords.AddRange(CSharpKeywords);
break;
case Language.HTML:
textbox.Settings.Comment = "<!";
string[] HTMLKeywords = getKeywords("APIs\\html.xml");
textbox.Settings.Keywords.AddRange(HTMLKeywords);
break;
case Language.Python:
textbox.Settings.Comment = "#";
string[] PythonKeywords = getKeywords("APIs\\python.xml");
textbox.Settings.Keywords.AddRange(PythonKeywords);
break;
}
}
UPDATE:
I have a folder in my project called APIs. I checked the file names several times. Here is the exception: Could not find a part of the path 'C:\Users\Mohit\Documents\Visual Studio 2010\Projects\Notepad\Notepad\bin\Debug\APIs\cs.xml'. Thats the EXACT path of the file!
There's little hope of your program ever finding that folder. When you deploy your app, there is no project folder. The best way to organize it is to add the .xml files to your project with Project + Add Existing. Select them in Solution Explorer and in the Properties window set Build action = None and Copy to Output Directory = Copy if Newer. Build. That puts the files in the same directory as your .exe.
Find them back at runtime with System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)
You might have better luck a fully qualified URL (eg #"D:\mypage\APIs\html.xml")
Looks like you are assuming the current directory is the install directory? You should find the directory like...
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) +
Environment.DirectorySeparatorChar +
"file you are looking for".
Are you sure your working directory is the right one? Try to print the absolute path of the . directory. Also, list it's contents and see if that directory really is there.
I'd recommend changing your getKeywords method to be something like this to aid debugging
public static string[] getKeywords(string filename)
{
var file = new FileInfo(filename);
if (!file.Exists)
{
throw new FileNotFoundException("The requested file was not found: " + file.FullName);
}
string[] keywords = XElement.Load(filename).Elements("Keyword").Attributes("name").Select(n => n.Value).ToArray();
return keywords;
}
This should give you the full path at which it was attempting to load the file, which should make the problematic path clear to you.
I tried #nobugz method and it worked. Once you set the properties of each *.xml file to:
The best way to organize it is to add the .xml files to your project with Project + Add Existing. Select them in Solution Explorer and in the Properties window set Build action = None and Copy to Output Directory = Copy if Newer. Build. That puts the files in the same directory as your .exe.
Then put this to get your path for each case in your switch case replacing "filename" with each filename you have.
string[] YourVar = getKeywords(string.Format("{0}\\APIs\\filename.xml", Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)));
Related
I try to get the Full Path of a File. ie. calc
Input: calc
Expected output: C:\WINDOWS\system32\calc.exe
I could find out how to do it with PowerShell:
(Get-Command calc).Source
Or with CommandLine:
where.exe calc
But unfortunately I can not get it done with C#.
The documentation for Get-Command says:
Get-Command * gets all types of commands, including all of the non-PowerShell files in the Path environment variable ($env:Path), which it lists in the Application command type.
So we will need to get the Path environment variable and iterate over the directories it lists, looking for files with extensions that indicate the file is a program, for example "*.com" and "*.exe".
The problem with the Path environment variable is that it can become polluted with non-existent directories, so we will have to check for those.
The case of the filename and extension don't matter, so case-insensitive comparisons need to be made.
static void ShowPath(string progName)
{
var extensions = new List<string> { ".com", ".exe" };
string envPath = Environment.GetEnvironmentVariable("Path");
var dirs = envPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string d in dirs.Where(f => Directory.Exists(f)))
{
foreach (var f in (Directory.EnumerateFiles(d).
Where(thisFile => extensions.Any(h => Path.GetExtension(thisFile).Equals(h, StringComparison.InvariantCultureIgnoreCase)))))
{
if (Path.GetFileNameWithoutExtension(f).Equals(progName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine(f);
return;
}
}
}
Console.WriteLine("Not found.");
}
static void Main(string[] args)
{
ShowPath("calc");
Console.ReadLine();
}
Output:
C:\WINDOWS\system32\calc.exe
There is always the possibility that the current user does not have permission to list the files from somewhere in the path, so checks should be added for that. Also, you might want to use StringComparison.CurrentCultureIgnoreCase for the comparison.
You can get the Pathenvironment variable, split it with ; as delimiter and loop over that result. Then, check if the file path + #"\" + name + ".exe" exists.
var findMe = "calc";
var pathes = Environment.GetEnvironmentVariable("Path").Split(';');
foreach (var path in pathes)
{
var testMe = $#"{path}\{findMe}.exe";
if (File.Exists(testMe))
{
Console.WriteLine(testMe);
}
}
This outputs :
C:\WINDOWS\system32\calc.exe
I do not know about any way of doing that exact thing from C# either. However the paths are usually well known and can be retreived via the SpecialFolders Enumeration:
using System;
using System.Diagnostics;
using System.IO;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
/*Note: Running a batch file (.bat) or similar script file as admin
Requires starting the interpreter as admin and handing it the file as Parameter
See documentation of Interpreting Programm for details */
//Just getting the Absolute Path for Notepad
string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
string FullPath = Path.Combine(windir, #"system32\notepad.exe");
//The real work part
//This is the programm to run
ProcessStartInfo startInfo = new ProcessStartInfo(FullPath);
//This tells it should run Elevated
startInfo.Verb = "runas";
//And that gives the order
//From here on it should be 100% identical to the Run Dialog (Windows+R), except for the part with the Elevation
System.Diagnostics.Process.Start(startInfo);
}
}
}
I did not just use System (37) back then, as I wrote it when x32/x86 Systems were still a thing. You would need to check how it resolves nowadays.
Note that most of those paths are duplicated in the PATH System Variable, so you could look it up: https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/
Path Variables in turn go back to the old DOS days. Basically if you gave the Commandline a command/filename it would try the build-in commands, then Executables in the current working Directory (.bat, .com, .exe), and then go look over the path directories to again look for executeables. And only if all that failed, would it complain.
I finally tried to combine all three answers and came up with this:
I post it here in case someone has the same problem.
public static string[] GetPathOf(string cmd)
{
var list = new List<string>();
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Machine).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Process).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.User).Split(';'));
list = list.Distinct().Where(e=>Directory.Exists(e)).SelectMany(e=> new DirectoryInfo(e).GetFiles()).Where(e=>Regex.IsMatch(e.Name,"(?i)^"+cmd+"\\.(?:exe|cmd|com)")).Select(e=>e.FullName).ToList();
return list.ToArray();
}
My application creates files and directories throughout the year and needs to access the timestamps of those directories to determine if it's time to create another one. So it's vital that when I move a directory I preserve its timestamps. I can do it like this when Directory.Move() isn't an option (e.g. when moving to a different drive).
FileSystem.CopyDirectory(sourcePath, targetPath, overwrite);
Directory.SetCreationTimeUtc (targetPath, Directory.GetCreationTimeUtc (sourcePath));
Directory.SetLastAccessTimeUtc(targetPath, Directory.GetLastAccessTimeUtc(sourcePath));
Directory.SetLastWriteTimeUtc (targetPath, Directory.GetLastWriteTimeUtc (sourcePath));
Directory.Delete(sourcePath, true);
However, all three of these "Directory.Set" methods fail if File Explorer is open, and it seems that it doesn't even matter whether the directory in question is currently visible in File Explorer or not (EDIT: I suspect this has something to do with Quick Access, but the reason isn't particularly important). It throws an IOException that says "The process cannot access the file 'C:\MyFolder' because it is being used by another process."
How should I handle this? Is there an alternative way to modify a timestamp that doesn't throw an error when File Explorer is open? Should I automatically close File Explorer? Or if my application simply needs to fail, then I'd like to fail before any file operations take place. Is there a way to determine ahead of time if Directory.SetCreationTimeUtc() for example will encounter an IOException?
Thanks in advance.
EDIT: I've made a discovery. Here's some sample code you can use to try recreating the problem:
using System;
using System.IO;
namespace CreationTimeTest
{
class Program
{
static void Main( string[] args )
{
try
{
DirectoryInfo di = new DirectoryInfo( #"C:\Test" );
di.CreationTimeUtc = DateTime.UtcNow;
Console.WriteLine( di.FullName + " creation time set to " + di.CreationTimeUtc );
}
catch ( Exception ex )
{
Console.WriteLine( ex );
//throw;
}
finally
{
Console.ReadKey( true );
}
}
}
}
Create C:\Test, build CreationTimeTest.exe, and run it.
I've found that the "used by another process" error doesn't always occur just because File Explorer is open. It occurs if the folder C:\Test had been visible because C:\ was expanded. This means the time stamp can be set just fine if File Explorer is open and C:\ was never expanded. However, once C:\Test becomes visible in File Explorer, it seems to remember that folder and not allow any time stamp modification even after C:\ is collapsed. Can anyone recreate this?
EDIT: I'm now thinking that this is a File Explorer bug.
I have recreated this behavior using CreationTimeTest on multiple Windows 10 devices. There are two ways an attempt to set the creation time can throw the "used by another process" exception. The first is to have C:\Test open in the main pane, but in that case you can navigate away from C:\Test and then the program will run successfully again. But the second way is to have C:\Test visible in the navigation pane, i.e. to have C:\ expanded. And once you've done that, it seems File Explorer keeps a handle open because the program continues to fail even once you collapse C:\ until you close File Explorer.
I was mistaken earlier. Having C:\Test be visible doesn't cause the problem. C:\Test can be visible in the main pane without issue. Its visibility in the navigation pane is what matters.
Try this:
string sourcePath = "";
string targetPath = "";
DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(sourcePath);
FileSystem.CopyDirectory(sourcePath, targetPath, overwrite);
DirectoryInfo targetDirectory = new DirectoryInfo(targetPath);
targetDirectory.CreationTimeUtc = sourceDirectoryInfo.CreationTimeUtc;
targetDirectory.LastAccessTimeUtc = sourceDirectoryInfo.LastAccessTimeUtc;
targetDirectory.LastWriteTimeUtc = sourceDirectoryInfo.LastWriteTimeUtc;
Directory.Delete(sourcePath, true);
This will allow you to set the creation/access/write times for the target directory, so long as the directory itself is not open in explorer (I am assuming it won't be, as it has only just been created).
I am suspecting FileSystem.CopyDirectory ties into Explorer and somehow blocks the directory. Try copying all the files and directories using standard C# methods, like this:
DirectoryCopy(#"C:\SourceDirectory", #"D:\DestinationDirectory", true);
Using these utility methods:
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
}
if ((dir.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
{
// Don't copy symbolic links
return;
}
var createdDirectory = false;
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
var newdir = Directory.CreateDirectory(destDirName);
createdDirectory = true;
}
// Get the files in the directory and copy them to the new location.
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
if ((file.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
continue; // Don't copy symbolic links
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
CopyMetaData(file, new FileInfo(temppath));
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
if (createdDirectory)
{
// We must set it AFTER copying all files in the directory - otherwise the timestamp gets updated to Now.
CopyMetaData(dir, new DirectoryInfo(destDirName));
}
}
private static void CopyMetaData(FileSystemInfo source, FileSystemInfo dest)
{
dest.Attributes = source.Attributes;
dest.CreationTimeUtc = source.CreationTimeUtc;
dest.LastAccessTimeUtc = source.LastAccessTimeUtc;
dest.LastWriteTimeUtc = source.LastWriteTimeUtc;
}
I am using the TFS API to get latest code files, directories, .csproj files, etc. under a TFS-bound folder.
For the same, I use something like the following:
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new
Uri(ConfigurationManager.AppSettings["TFSUrl"]));
tfs.EnsureAuthenticated();
var vsStore = tfs.GetService<VersionControlServer>();
string workingFolder = #"C:\TFS\SolutionFolder";
Workspace wsp = vsStore.TryGetWorkspace(workingFolder);
if (wsp != null)
{
ItemSet items = vsStore.GetItems(workingFolder, VersionSpec.Latest, RecursionType.Full);
string relativePath = workingFolder + #"/";
foreach (Item item in items.Items)
{
string relativePath1 = item.ServerItem.Replace("$/TFS/SolutionFolder", relativePath);
if (item.ItemType == ItemType.Folder)
{
Directory.CreateDirectory(relativePath1);
}
else
{
item.DownloadFile(relativePath1);
}
}
}
Now, I get the items to download and then download happens. However, I want it to be like how VS handles it - if (and only if) there is a change in a file/folder, then only download the same. With this code, I always get 'n' number of files/folders in that folder and then I overwrite the same. Wrong approach, I know. I can, however, modify this code to check for the folder's or file's last change time and then choose to either overwrite it or ignore it. That's an option, albeit a bad one at that.
Now, what I would ideally like is to get ONLY the list of files/folders that actually need to be changed i.e. the incremental change. After that, I can choose to overwrite/ignore each item in that list. So, in the present case, if a new file/folder is created (or one of the existing ones got changed inside $/TFS/SolutionFolder i.e. in the sever), then only I want to pull that item in the list of files/folders to change(and decide what I want to do with it inside C:\TFS\SolutionFolder).
Also, is using one of the overloads of VersionControlServer.QueryHistory() an option? I had something like this:
(latestVersionIdOf $/TFS/SolutionFolder) - (existingVersionIdOf C:\TFS\SolutionFolder) = (Versions that I'd go out and get back from the server, for that folder)
in mind.
Any pointers will be very helpful. Thanks!
Just use Workspace.Get() or overload method (wsp.Get()), it just update updated files.
I don't think we can achieve that. If the files are downloaded to a folder without in source control, there are no versions compared within the folder, even if the folder is in source control, the behavior is just download also no version compare actions. So, it will download all the files ever time and then overwrite the same ones.
In VS, the files are all in TFS source control system, so when we Get Latest Version the changed/added files will be retrieved from TFS. If you want to get the same behavior as VS handles, you can use the tf get command. See Get Command
You can reference this article to use the tf get command :
get-latest-version-of-specific-files-with-tfs-power-tools
Update :-
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConfigurationManager.AppSettings["TFSUrl"]));
tfs.EnsureAuthenticated();
var vsStore = tfs.GetService<VersionControlServer>();
string workingFolder = ConfigurationManager.AppSettings["LocalPathToFolder"]; // C:\TFS\SolutionFolder
string tfsPathToFolder = ConfigurationManager.AppSettings["TFSPathToFolder"]; // $/TFS/SolutionFolder
Workspace wsp = vsStore.GetWorkspace(workingFolder);
if (wsp != null)
{
ItemSpec[] specs = { new ItemSpec(tfsPathToFolder, RecursionType.Full) };
ExtendedItem[][] extendedItems = wsp.GetExtendedItems(specs, DeletedState.NonDeleted, ItemType.Any);
ExtendedItem[] extendedItem = extendedItems[0];
var itemsToDownload = extendedItem.Where(itemToDownload => itemToDownload.IsLatest == false);
foreach (var itemToDownload in itemsToDownload)
{
try
{
switch (itemToDownload.ItemType)
{
case ItemType.File:
if (itemToDownload.LocalItem != null)
{
vsStore.DownloadFile(itemToDownload.SourceServerItem, itemToDownload.LocalItem);
}
else
{
string localItemPath = itemToDownload.SourceServerItem.Replace(tfsPathToFolder,
workingFolder);
vsStore.DownloadFile(itemToDownload.SourceServerItem, localItemPath);
}
break;
case ItemType.Folder:
string folderName = itemToDownload.SourceServerItem.Replace(tfsPathToFolder, workingFolder);
if ((!string.IsNullOrEmpty(folderName)) && (!Directory.Exists(folderName)))
{
Directory.CreateDirectory(folderName);
}
break;
}
}
catch (Exception e)
{
File.AppendAllText(#"C:\TempLocation\GetLatestExceptions.txt", e.Message);
}
}
}
This code works well, except:
a. Whenever it downloads the latest copy of, let's say a file, it 'checks it out' in TFS :(
b. For some items, it throws errors like 'Item $/TFS/SolutionFolder/FolderX/abc.cs was not found in source control at version T.' - I have to find out what the exact cause of this issue is, though.
Any ideas on how to get around these two issues or any other problems you see with this code? Thanks!
This question already has answers here:
See if file path is inside a directory
(2 answers)
Closed 9 years ago.
How can I check in C# if the specific path is to directory in "Program Files" ?
C:\Program Files\someDir... -> is in Program Files
D:\Apps\someDir... -> isn't in Program Files
Thanks!
You can check a path in ProgramFiles(x86) by using the code below:
string path = "yourpath";
var programfileX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
if (path.IndexOf(programfileX86, StringComparison.OrdinalIgnoreCase) >= 0)
{
//Found path
}
There're some interseting and subtle issues with the problem:
You should compare paths case insenstive, e.g. "C:\PRogRAM FILES (x86)\Sample" is OK
Separators could be either / or \ so "C:/PRogRAM FILES (x86)/Sample" is OK as well
You should break on separatos only, e.g. "C:\Program Files (x86)MyData\Sample" is not OK
The Code:
public static Boolean PathIncludes(String path, String pathToInclude) {
if (String.IsNullOrEmpty(pathToInclude))
return false;
else if (String.IsNullOrEmpty(path))
return false;
String[] parts = Path.GetFullPath(path).Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar);
String[] partsToInclude = Path.GetFullPath(pathToInclude).Split(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar);
if (parts.Length < partsToInclude.Length)
return false;
for (int i = 0; i < partsToInclude.Length; ++i)
if (!String.Equals(parts[i], partsToInclude[i], StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
public static Boolean InProgramFiles(String path) {
return PathIncludes(path, Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)));
}
// Tests:
// Supposing that ProgramFilesX86 is "C:\Program Files (x86)"
InProgramFiles(#"C:\PRogRAM FILES (x86)\Sample"); // <- true
InProgramFiles(#"C:/PRogRAM FILES (x86)/Sample"); // <- true
InProgramFiles(#"D:/PRogRAM FILES (x86)/Sample"); // <- false
InProgramFiles(#"C:/PRogRAM FILES (x86)A/Sample"); // <- false
First you need to get the program files path. You can do that with System.Environment:
var programFilesPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
If you want the 32 bit program files path you would just change the special folder you are looking for (System.Environment.SpecialFolder.ProgramFilesX86). Then I would do a contains:
var isInProgramFiles = myPath.ToLower().Contains(programFilesPath.ToLower());
That should get you 90% of the way there at least! Best of luck!
EDIT / Sanitize Note
As a side note - there are situations where you can have a valid input and this still wouldn't match. For example - using "/" instead of "\". If you want to make sure you handle these boundary cases correctly, you can create a "DirectoryInfo" object from your input string, validate that it is actually a folder and also standardize the formatting for it. That code looks something like:
if (!System.IO.Directory.Exists(inputPath)) return false;
var checkPath = (new System.IO.DirectoryInfo(inputPath)).FullName;
In this example "inputPath" is the same as "myPath" was above. That should do a moderately good job of sanitizing the input. Best of luck!
If you have a path variable:
string path = "/* whatever path */";
You can check if it is in a folder subfolder this way:
path.IndexOf('\\' + subfolder + '\\') != -1
Note that in more complex cases .. may revert you out of a subdirectory, meaning that you are not in folder f2 if you have something like this:
"\\base_on_drive\\subfolder\\f1\\f2\\..\\a_file.txt"
The .. will bump you back into it's parent folder f1.
if (path.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)) || (path.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)))
{
}
Assuming your program might be running inside of ProgramFiles, you will probably want to get the fullpath of any path you're checking (in case you get a relative path). In addition, C# has a handy SpecialFolder enumeration that you can use to get the ProgramFiles directory.
The following code will take in a path, convert it to a fullpath, and check if the ProgramFiles directory can be found inside of it. You may want to add some error handling (such as checking for null paths).
static string programfileX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
public bool IsInsideProgramFiles(string path)
{
// Get the fullpath in case 'path' is a relative path
string fullPath = System.IO.Path.GetFullPath(path);
return (fullPath.IndexOf(programfileX86, StringComparison.OrdinalIgnoreCase) >= 0);
}
Note: Depending on the systems your code is running in, you may want to check for both SpecialFolder.ProgramFiles and SpecialFolder.ProgramFilesx86.
Credit goes to Toan Nguyen's for the code to get the ProgramFiles directory:
I have my program setup to rename and store a file according to checkbox input. I used another stackoverflow post for my template. Only problem is when I tried setting it up for sub-folders, it never puts it in the correct folder. I have a label folder with two sub folders called L-Labels and B-Labels. The user checks which label type it is and the file gets renamed and placed in the according sub-folder. When I used breakpoint my variables are getting the correct value so I don't see what's wrong I have provided my variables and code for relocating the file. What is causing this to not put it in my sub-folder?
Varibales:
string oldPath = lblBrowseName.Text;
string newpathB = #"C:\Users\Public\Labels\B_Labels";
string newpathL = #"C:\Users\Public\Labels\L_Labels";
Method:
if (rChkBoxBizerba.Checked == true)
{
string newFileName = rtxtBoxNewVersion.Text;
FileInfo f1 = new FileInfo(oldPath);
if (f1.Exists)
{
if (!Directory.Exists(newpathB))
{
Directory.CreateDirectory(newpathB);
}
f1.CopyTo(string.Format("{0}{1}{2}", newpathB, newFileName, f1.Extension));
if (System.IO.File.Exists(lblBrowseName.Text))
System.IO.File.Delete(lblBrowseName.Text);
}
I would say this is the problem:
f1.CopyTo(string.Format("{0}{1}{2}", newpathB, newFileName, f1.Extension));
You declare your path but it doesn't have a trailing directory separator, so when you combine all the parts, as above, the actual result is invalid.
You really should use Path.Combine() to combine parts of paths together, this uses the correct directory separator and makes additional checks.
Try something like this:
// Build actual filename
string filename = String.Format("{0}{1}",newFileName, f1.Extension));
// Now build the full path (directory + filename)
string full_path = Path.Combine(newpathB,filename);
// Copy file
f1.CopyTo(full_path);