I want to create a folder in my VB .NET app but I can't get to verify that the path is correct. For example, if I enter
My.Computer.FileSystem.CreateDirectory("lol it will work")
It works... While it doesn't look like a folder path at all... How can I verify that the path entered is correct ? And since it doesn't throw any exception, the folder must be created somewhere, but where ? I can't find it...
Thank you
Your Directory name "lol it will work" is a valid name.
When you don't provide an explicit path, My.Computer.FileSystem.CreateDirectory() (as well as some other methods/functions) will assume the string you provided is the path to a directory which relative path is your Application's current directory.
So it doesn't matter whether you're passing a complete path (that looks like a valid folder path) or a partial path/folder name that will be associated with the application's Directory as long as :
the resolved Path is a valid path (that doesn't contains invalid chars or missing folder name separator)
you (your application) have access to that path
the resulting path doesn't exceed the max allowed number of characters.
you don't encounter some specific Exceptions...
So, how do you know your application current working path ?
Since you used My.Application.FileSystem :
My.Computer.FileSystem.CurrentDirectory ' Read/Write Property As String
You can use System.IO :
System.IO.Directory.GetCurrentDirectory() ' Get a String
System.IO.Directory.SetCurrentDirectory(NewPath) ' Set
You can also use System.Environment.Directory
Environment.CurrentDirectory ' Read/Write Property As String
Both three (My.Computer.FileSystem, System.IO.Directory and Environment) are writable, and returns the current directory to be resolved in case you're providing relative paths in your application.
So, to answer your question : "How can I verify that the path entered is correct ?"
If you just created the Directory and you get no exception, then the name of your (relative) directory is valid, and the directory has been created :
My.Computer.FileSystem.CreateDirectory("lol it will work")
' Verification :
If System.IO.Directory.Exists("lol it will work") Then
MessageBox.Show("The Directory has been created !")
Else
MessageBox.Show("The Directory has'n been created !")
End If
' Shows "The Directory has been created !"
So you know that even other Functions/Methods can resolve relative path (not all though) by fallbacking to the defined Relative Working Path of your Application.
The test above is the same as :
System.IO.Directory.Exists( _
Path.Combine(Environment.CurrentDirectory, "lol it will work"))
CAUTION :
Due to the writable nature of those objects, your application
may change the Current Directory any time.
Consider :
the use of alternative objects/variables to get your working directory or similar
working with only explicit paths
using a global/static variable that stores the CurrentDirectory upon startup (can fail very easily)
restoring the CurrentDirectory whenever you're changing it (though you will use at a time or another an object that changes the CurrentDirectory without warning - read the documentation of that object whenever it involves a directory manipulation; OpenFileDialog for example which has different behaviours on XP and Win7/8) - This move is the least recommended.
Alternates :
AppDomain.CurrentDomain
AppDomain.CurrentDomain.BaseDirectory
This is a ReadOnly Property. It returns the path to the directory your assembly (application) were loaded from. Caution ! This path has a trailing "\" like :
G:\Tools\...\Sources\bin\Debug\ ' <- !!!
Assembly.GetExecutingAssembly().Location
System.IO.Directory.GetParent(Assembly.GetExecutingAssembly().Location)
This will also return the path to the directory the assembly were loaded from, but without the trailing "\" due to the use of GetParent()
Using Assembly to retrieve a path is useful when you're dealing with dependencies where not all Assemblies are loaded from the same directory. Codes that uses relative paths should use this approach instead of the classic ones.
I assume the same applies for Thread Domain if you want to get deep in multithreads (while I'm not really sure of the relevant aspect of this assumption - Never used this one !) :
Thread.GetDomain().BaseDirectory ' ReadOnly
And the good old Application.StartupPath
Application.StartupPath ' ReadOnly
...which also has a trailing "\". You can't access StartupPath until the application has actually started ! However, I've never checked whether it's working well when you start another process from your application and using that through the other process... (if it's possible... just imagining though)
Related
If I use this statement in a file watcher routine, how do I access what the directory path is that the change occurred in?
watcher = New FileSystemWatcher With {.NotifyFilter = NotifyFilters.DirectoryName Or NotifyFilters.FileName Or NotifyFilters.Attributes}
I used the full path member in the handler method, but it gives me the directory as well as the file name. So I just want to get the directory affected. How would I access that?
I used the
Path.GetDirectoryName(filePath)
that GSerg suggested, and this was the statement that I needed to find the directory name that I was searching for. This solved my problem.
I would like to point new users to the proper directory to where the file type may be found. However, I don't want to hamper the efficiency of experienced users, as there are more specific sub folders that they may wish to remain in throughout multiple file openings.
I found some context for openfileDialog for c++ here: Initial directory is not working for CFileDialog
However I am interested in a VB solution. Here is Microsoft's documentation:
https://msdn.microsoft.com/en-us/library/system.windows.forms.filedialog.initialdirectory(v=vs.110).aspx
in which they state
The InitialDirectory property is typically set using one of the following sources:
A path that was previously used in the program, perhaps retained from the last directory or file operation.
Here is my code:
If Not ImportDialog.InitialDirectory.Contains("Direct Access\Shell\Customer Invoices") Then
ImportDialog.InitialDirectory = "....\Direct Access\Shell\Customer Invoices\"
End If
How can I determine if a user would automatically be sent to this directory or a subdirectory in the tree if getting InitialDirectory is unreliable?
I saved the most recently opened folder and redirected the file path depending on if the user preferred a different path:
If _lastOpenFolder = "" Then
ImportDialog.InitialDirectory = "Direct Access\Shell\Customer Invoices\"
Else
ImportDialog.InitialDirectory = _lastOpenFolder
End If
If ImportDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
_lastOpenFolder = ImportDialog.FileName.Substring(0, ImportDialog.FileName.LastIndexOf("\"))
_lastOpenFolder = _lastOpenFolder.Substring(0, _lastOpenFolder.LastIndexOf("\"))
End If
In a VB.NET application I need to set a button to start a program - specifically, Steam. But I need to allow for the user having installed the program somewhere other than the default location "C:\Program Files (x86)\Steam". So all I know is the executable name: "steam.exe".
In searching for an answer it looks like I should be able to get the path using Microsoft.Win32.Registry somehow, but the examples I'm seeing aren't helping me (I guess I'm just not getting how to apply those examples to my situation).
This tutorial gives the example of finding the path to the excel executable:
Dim regKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\MICROSOFT\Windows\CurrentVersion\AppPaths\excel.exe")
Dim path As String = regKey.GetValue("Path").ToString
But I'm getting a value of "Nothing" for regKey. Not only that, even if it did get a value for regKey, how would I know the registry path for another program (Steam, in my case)?
And how much will the version of Windows change the possible registry location of a program - if at all?
How do you get the path of the App_Data folder in the Seed method of the configuration class of code first migrations.
I want to read from a file I've put in the App_Data folder and the Seed method runs after the update-database command. HttpContext.Current.Server.MapPath obviously does not work because there is no HttpContext at that point.
I got it to work with something like:
string MyPath = AppDomain.CurrentDomain.BaseDirectory + "/../App_Data"
because AppDomain.CurrentDomain.BaseDirectory ends at the "/bin" directory.
Here is a quick-and-dirty way to get you started:
var myPath = AppDomain.CurrentDomain.BaseDirectory;
//to quickly show the path, either attach another debugger or just throw an exception
throw new Exception(myPath);
#Rusty Divine gave a good answer, however maybe you will find this is better for you:
System.IO.Path.Combine( System.Text.RegularExpressions.Regex.Replace(AppDomain.CurrentDomain.BaseDirectory, #"\\bin\\Debug$", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase) , RELATIVE_PATH, "FILENAME.EXE");
For example:
System.IO.Path.Combine( System.Text.RegularExpressions.Regex.Replace(AppDomain.CurrentDomain.BaseDirectory, #"\\bin$", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase) , "App_Data\\Init", "fileName.txt");
In that way (using Regx), we make sure the only replace could be is at the suffix (at the end) of the AppDomain.CurrentDomain.BaseDirectory String. If there is sub folders in the server path named: "\bin\Debug" they won't be replaced.
This solution is case insensitive, meaning "\BIN\debug" will also be replaced.
Moreover, you don't need to append the strings to one string.
System.IO.Path.Combine will do it for you.
For what it's worth... you need to do a string replace if you are going to use BaseDirectory in your unit test. But, this still has the problem that it uses the path of your unit test project so be weary of that if you are trying to point to files in another project. In this case you will have to hard code the path.
AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin\\Debug","") + "\\App_Data";
I'd like to download a file using HTTP. How do I do it?
I have investigated this further and have re-ordered my suggestions from last week as a result:
The class 'CHttp' in VO's 'Internet' library has a method GetFile (the VO 2.5 "what's new" has a brief description on page 10). I've not tried it, though. You'll probably want something like this:
local oSession as CHttp
local lSuccess as logic
oSession := CHttp{}
oSession:ConnectRemote("foo.example.com") // Server domain name
lSuccess := oSession:GetFile("bar/baz.pdf",; // Remote filename
"c:\temp\baz.pdf",; // Local filename
lFailIfAlreadyExists)
oSession:CloseRemote()
// If lSuccess, the file should be downloaded to cLocalFileName.
// I don't know whether the filename arguments should use / or \ for directory separators.
I think another way is to use the Windows ShellExecute function to invoke an external program which downloads the file. I found an example of ShellExecute here. I haven't tried this as I don't have a VO compiler (or help file!) available to me at the moment. I'm not sure whether this is a good way or not, and I don't know whether it's safe from people trying to run a malicious command by supplying a sneaky filename. But I think the following might work. It assumes you have the program curl.exe (see: curl) on your path, which is used for downloading the file. You may need the fully path of curl.exe instead. I'm not sure where the file will be saved by default (I think you can specify a working directory in the parameter labelled lpDirectory)
local cParameters as string
local cURL:="http://www.example.com/interesting.htm" as string
local cLocalFile:="savefile.html" as string
cParameters := "-o "+cLocalFile+" "+cURL
ShellExecute(NULL /*Window handle*/,;
String2PSZ("open"),;
String2PSZ("curl.exe"),;
String2PSZ(cParameters),;
NULL_PTR /* lpDirectory */,;
SW_SHOWNORMAL)
See also the MSDN page for ShellExecute.
There appears to be a method App:Run(cCommand) which can be used to start external applications