3

Okay. I feel like this should be programming 101, but I cannot seem to find a decent answer on how to set a file path name to be dynamic enough to be set explicitly to where the exe is installed.

Basically, this application is actually going to be installed in the Users personal folders, probably something like Local Data, and I need to get a txt file that is created by the program to be created into the same directory as the executable.

Current Path:

Dim strFilePath As String = "D:\Development\Bobby\Prototyping\Replication Desktop Client\Replication_Desktop_Client\ClientAccessList.txt"

I want to set it to something like

Dim strCurrentLocationOfEXE As String = HardDriveLetter & Users & CurrentUserPath & InstalledDirectory
Dim strFilePath As String = strCurrentLocationOfEXE & "\ClientAccessList.txt"`

but I can not for the life of me figure out how to get it to determine that, since it is not going to always be installed to the same folder (i.e. Username and perhaps hard drive letter will be different).

Ideas?

Bobby Nicholls
  • 101
  • 2
  • 9
  • You need to look for OS specific environement variables ... Look here for an introduction: http://en.wikipedia.org/wiki/Environment_variable – Minus Apr 08 '13 at 19:14
  • Let me change it up by asking, will this work to save the txt file in the users roaming app data folder, and will it correctly create the Replication Client folder as well? `Dim strCurrentAppDataPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData & "\Replication Client") Dim strFilePath As String = strCurrentAppDataPath & "\ClientAccessList.txt"` – Bobby Nicholls Apr 08 '13 at 19:18
  • If you want to create a new folder, you'll need to explicitly create it as a separate step. It's better to use `Path.Combine` rather than concatenating the paths directly yourself. – Steven Doggart Apr 08 '13 at 19:24
  • Gotcha, that was what I was thinking. Is there a reason that using path.combine is better than concatenating it myself? – Bobby Nicholls Apr 08 '13 at 19:26
  • Concatenating will certainly work, it's just that `Path.Combine` gives you that added layer of abstraction in case the format of a path is different than expected in the current operating system. For instance, it's feasible that someone may be running your app on a linux machine under Mono, in which case the forward slash ought to be used instead of a backslash. It's not a big deal, but it's just good practice. – Steven Doggart Apr 08 '13 at 19:37
  • Gotcha, luckily, the market for this application consists of only windows users, the clients that use this cannot have Linux machines due to the requirements of their other contracts, so I am not too worried about it, but I will definitely keep that in mind in case something changes. – Bobby Nicholls Apr 08 '13 at 19:43

2 Answers2

2

You can get the path where the assembly is running with

Dim fullPath = System.Reflection.Assembly.GetExecutingAssembly().Location
Dim folderName = Path.GetDirectoryName( fullPath )
Dim strFilePath = Path.Combine(folderName, "ClientAccessList.txt")

if you want to refer to the current user personal folder for this application then the way to go is through the Environment.SpecialFolder enumaration.
This enum is independent from the underlying OS (XP, Win7, x64, x32 etc) In this case you could use:

Dim fullPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Dim strFilePath = Path.Combine(fullPath, "your_app_reserved_folder", "ClientAccessList.txt")

In this example "your_app_reserved_folder" should be a folder created during installation of your application where you put per user data files. (Usually this is the recommended way to go to store data files that should be kept separated by user)

If you want to check the existence of the folder before trying to use it just encapsulate the logic to get the file name in a method

Public Function GetUserAppClientAccessList() As String

    Dim fullPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    Dim appFolder = Path.Combine(fullPath, "your_app_reserved_folder")
    if Not Directory.Exists(appFolder) then
        Directory.Create(appFolder)
    End If
    return = Path.Combine(appFolder, "ClientAccessList.txt")
End Function
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Okay, so I have a change to my question. take a look at the question comments – Bobby Nicholls Apr 08 '13 at 19:17
  • This works returning the path from where the assembly is running. It could be different from the Roaming or Local folder for the current user. If you want a indipendent path from the user folder then the way to go is Environment.SpecialFolder enumeration – Steve Apr 08 '13 at 19:20
  • Mhmm... So I am thinking I don't want the txt file saved into the assembly location, just in the users roaming appdata. what I need to know is, Am I going to have to also create logic that checks to see if the folder "Replication Client" exists as well before trying to set the folder data path? Or will it automatically create on if it isn't there...? – Bobby Nicholls Apr 08 '13 at 19:25
  • No, as I have said, the folder doesn't exist automatically just because you are referencing it. However it is really simple to check the existence of the folder. – Steve Apr 08 '13 at 19:28
0

This will give you the file path of the executable:

Assembly.GetEntryAssembly().Location

And then to get the folder path, you can call Path.GetDirectoryName. So, to get the text file path, you can do something like this:

Dim exeFilePath As String = Assembly.GetEntryAssembly().Location
Dim exeFolderPath As String = Path.GetDirectoryName(exeFilePath)
Dim filePath As String = Path.Combine(exeFolderPath, "ClientAccessList.txt")

One bit of caution though: Assembly.GetEntryAssembly can return Nothing if there is no .NET assembly executable, such as if the code is being called as a library via COM. In that case, you may want use the executable file path from the command line by calling Environment.GetCommandLineArgs()(0). And if that fails, for some reason, you could always resort to Directory.GetCurrentDirectory().

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105