This is probably a rudimentary question but I am still kinda new to programming and I've wondered for awhile. I've done multiple projects in Python, C#, and Java, and when I try to use new libraries (especially for Python) people always say to make sure its in the right PATH and such. I just followed an online tutorial on how to install Java on a new computer and it rekindled my question of what a path really is. Is the Path just were the programming language looks for a library in the file system? I get kinda confused on what it's significance is. Again, I'm sorry for the wide question, its just something that I've never quite gotten on my own programming.
EDIT: I just wanted to thank everyone so much for answering my question. I know it was a pretty dumb one now that I've finally figured out what it is, but it really helped me. I'm slowly working through as many C#, Java and Python tutorials as I can find online, and it's nice to know I have somewhere to ask questions :)
The PATH is an environment variable which the shell (or other command interpreter) uses to search for commands. Usually (always?) commands are found with a greedy algorithm, so entries that come first in the PATH are returned first. For example, a command in /usr/local/bin will override a command in /usr/bin given a PATH such as
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
while the purpose is consistent, the syntax is slightly different on WINDOWS - you would use
C:\> ECHO %PATH%
to "echo" your PATH.
First my shell is going to search /usr/local/sbin then /usr/local/bin then /usr/sbin and then /usr/bin before searching /sbin and /bin if the command isn't found then it will report that it couldn't find such a command...
# Like so
$ thisprogramdoesntexist
thisprogramdoesntexist: command not found
Now, on Linux at least, there's also a LD_LIBRARY_PATH which the system will use to search for dynamic libraries (greedily), on Windows I think it just uses the PATH. Finally, Java uses a CLASSPATH which is similar (but used to search for classes and JARs).
On Linux one might add an entry to the PATH like so,
$ export PATH="$PATH:/addNewFolder"
While on Windows you might use
set PATH=%PATH%;c:\addNewFolder
Sometimes, you might manipulate your PATH(s) to enable specific functionality, see update-java-alternatives on Ubuntu for an example.
A PATH is a file directory on your computer. If you need to install a programming language, you might need to put it in your system PATH variable. This means that the system looks to these files for different information, IE where the libraries for the code you are using are.
Hope that helped!
Exactly as other said, PATH is a list of folders that is included in the search -other than the current folder- and you can always access straight away. It's one of the Environment Variables.
For example, we have the python folder in C:\Python27. I'm sure you know that to run a python file, we commonly use python script.py.
What happens is that the command line searches for python.exe in your current folder, and if not found, search it in the folders in the path variable.
To read the path, you can, straightforwardly use:
$ PATH
If you're on windows, like i am, an easy way to deal with this is to just use System Properties. Just type it in the start menu, open it, and go to the 'advanced' tab. Click on the Environment Variables, there! You'll see a PATH variable, and you can modify it as you want.
I myself use more than one version of Python, and to deal with this, i appended all the folders to PATH, and changed my python.exe to pythonversion_number.exe. Problem solved! Now, i can run this in the command line:
$ python26 script.py
$ python33 script2.py
Some further reading on this, if you're interested, here's a good question asked
Hope this helps!
The best resource (so far) about PATH information, you can see in this question:
https://superuser.com/questions/284342/what-are-path-and-other-environment-variables-and-how-can-i-set-or-use-them
Stack Overflow is not the best place to search about this, always check the amazing
https://superuser.com/ for this kind of question.
PATH is a symbolic name usually associated to string values separated by a semicolons (where each string part is a directory name). This symbolic name (and its values) is handled by the operating system and could be modified by the end user through the some command line instruction like SET PATH=........ or through some kind of user interface configuration tool.
It is common practice for tools like compilers or other programming tools to look at this symbolic name and use the list of string values for searching files that are not directly available in the current folder used by the tools.
So, if an installation procedure set the PATH symbol in this way
SET PATH=%path%;C:\PROGRAM FILES\MYTOOLFOLDER;
it means, set the PATH symbol to the previous value (%PATH%) and add another string value to it (C:\PROGRAM FILES\MYTOOLFOLDER).
Then the tool, when it needs to search for a particular file or library, could read the PATH symbol values, split them at the semicolons and iteratively look at the directories listed one by one looking for the file required.
In C# programming, for example, the tool code could contain something like this
string pathSymbol = Environment.GetEnvironmentVariable("PATH");
string[] pathFolders = pathSymbol.Split(';');
foreach(string folder in pathFolders)
{
if(File.Exists(Path.Combine(folder, "mylibrary.dll"))
{
..... do whatever you need to do with the file
}
}
This example assumes a Windows environment.
Related
I would like to find all file paths that are not filtered by a .gitignore (or any nested .gitignore files within sub-directories) using C#. This is similar to the question here with regard to PHP. I'm wondering if someone knows if this code had already been made available (in C#) somewhere online.
UPDATE: To answer what I want this for, it is so I can run my own little periodic backup of my source files for certain projects (zipping the result), for added peace of mind. The hard part is getting a robust .gitignore parser to get the filtered file paths (and exclude the others), without wanting to become too embroiled in learning that spec if someone else already has done it for me.
Well, the best way to parse .gitignore files (and the other files Git uses, such as $GIT_DIR/info/exclude) is to get Git to do it for you. :-) (In your case, most cases in fact, this does involve executing a git subprocess.)
git check-ignore
The git check-ignore command can be used to detect which files are ignored and why. The --non-matching option makes it tell you about files that are not ignored as well, though since it still tells you about ignored files, too, and in a special format, you'll need to do a little bit of further work to get a simple list of non-ignored files. This Bourne shell function does the trick:
find_nonignored() {
find . -path ./.git -prune -o -print \
| git check-ignore --verbose --non-matching --stdin \
| sed -n -e 's,\t./,\t,' -e 's,^::\t*,,p' \
}
How It Works
The find command finds all files in and below the current working directory, which should be somewhere in the tree you're trying to filter. We exclude the top-level .git subdirectory and everything under it from the output, if present; /.git/ is not in a typical .gitignore file because Git ignores it automatically and thus is is normally considered "not ignored" by git check-ignore.
git check-ignore will print out --non-matching files only in --verbose mode because it's only in that mode where it prints out the extra information that would tell you if the file is ignored or not. (It always prints ignored files.) The paths come out one per line in the format
source:linenum:pattern<TAB>path
The colon-separated fields are information about what caused the path to be ignored (such as a line in the .gitignore file) and will be empty if the file is not ignored.
The sed command then filters the output to show only the paths of the ignored files. The -n option tells it not to print out the input lines by default. The first substitution pattern replaces <TAB>./ with just <TAB>, removing the leading ./, for purely aesthetic reasons. The second substitution does the real work, removing any ::<TAB> (indicating no "ignore" information) that starts a line and, if that substitution happened, printing what's left of the line which is a non-ignored path.
You can filter this further to do additional processing; I built this for a script that does markdown checking along these lines:
markdownlint $(find_nonignored | grep '\.md$')
Notes
This code includes untracked files (i.e., have never been added to the Git repo or staged) in the output, which is usually what you want. (Test systems, for example, should still check new files even before they've had git add run on them.) Beware that other solutions involving git ls-files and the like usually don't do this.
The above code relies on using GNU sed, which interprets \t as a tab. If you're using BSD sed (such as on MacOS) you probably need to tweak this slightly. Check the comments to see if someone has a hint for this.
All the code here breaks on paths with spaces or other "unusual" characters; it needs to be modified in several places (such as using -print0 with find) to fix this. I do not address issues like this here in order to keep the explanation simple. I also leave for others the generalization of the function to work on arbitrary paths rather than just the current working directory.
It's difficult to make suggestions without knowing exactly what you want to do with the list (use it in a build script, process the files in some way, just view them on a UI, etc.)
I couldn't find one in C#, but this JavaScript gitignore parser doesn't have a lot of code to convert and it exposes both an accepts and a denies method to get a list of included or ignored files. It is fairly well documented, has tests, and the regular expressions it uses would work just as well in C# as they do in JavaScript.
This answer would work from C#, provided you have Git installed on the machine where your C# code is running.
Also note that the Git Source Control Provider plugin for Visual Studio provides the list right in the IDE, along with the ability to check boxes and commit certain files together and a lot of other functionality that is difficult to do on the command line.
NOTE: The Git Source Control Provider is open source (written in C#) and you can view the source here, but it may be much more involved to reverse engineer than the JavaScript project.
For those looking for a C# library, you can check this out as well.
.gitignore based parser implemented in C# according to the .gitignore spec 2.29.2. The library is tested against real git status outputs. The tests use LibGit2Sharp for that.
https://github.com/goelhardik/ignore
It's kind of a port of other open source libraries and so far looks like it works well for my other projects.
I work for an IT company where we all carry around flash drives that have our most used programs on them.In my spare time I am hoping to create a "main menu" item that is kind of a fun and convenient way to access these files. I am working on creating this using Visual Studio 2013 and using visual C# windows forms. I have come across a snag however that I can't seem to find a workaround for. I am by no means fluent in C#, but I need to have a button on the windows form open a file without specifying what drive it comes from. I understand that I have to specify a path, but as these will be stored on the flash drives of myself and my coworkers I cannot foresee that the path will always begin with E:. Depending on what USB slot the drive is plugged into it could be N: or F: or the like. I have provided an example below:
Using what I currently know I am opening files using this line of code:
System.Diagnostics.Process.Start("C:/Users/Myname/Desktop/Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
Is there any way possible I can have the file open simply from
System.Diagnostics.Process.Start("Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
or something of that nature?
Thanks in advance.
There must have been some mis-communication when I asked my question previously. what I am looking to do is open an executable file via a button click on the windows form using a relative path. I am not able to specify the absolute path because the application will be run from a flash drive and therefore will change depending on what USB slot it is currently inserted into.
What I am hoping to accomplish is insert a line of code that will allow me to open an executable file that is located in the \bin\debug folder along with the application itself. I have a picture for clarification but apparently do not have enough reputation to post it. Thank you and sorry for the earlier confusion.
Usually you can just use Environment.GetFolderPath (MSDN) to give you what you need. It doesn't do absolutely everything, but if you need Desktop and the like, that is plenty.
Depending on the target version of .Net, the SpecialFolders exposed are not all there. It may turn out that you need more than they provide, but in your case it doesn't sound like it.
If there is more you need that is not covered in the default, check out this project. I'm sure there are others like it, but it does a little more than the default BCL version, using the API directly. It is at least something to read and learn (and translate from vb.. use an online translator, very quick). I haven't looked at it, but it seems like you are learning this c#/.net thingy, so it might be helpful
This article is about accessing Windows special folders.
These folders include your “Favorites”, “Cookies”, system libraries and the like.
Here is code, including a large number of constant definitions, plus documentation,
allowing access to and creation of these folders.
I'm wondering is there any way to use the normal shortcuts form windows like %PROGRAMFILES%, %APPDATA%,.... when using System.Diagnostics.Process.Start ?
What I want to do there is using one of those shortcuts to dynamically create the path that is being used to tart the program I want to start with Process.Start.
Example:
System.Diagnostics.Process.Start("%PROGRAMFILES%\MyApp\MyApp.exe");
Edit: As a comment to the accepted answer:
As one important thing was mentioned in the comments I want to also put it here:
If the solution does not work as the file is not found, one should print out the result of the System.Environment.ExpandEnvironmentVariables command. It can be that it points unintendedly to the x86 program files location instead of the program files location (or vice versa) depending on if for the application itself (project properties) "Prefer 32-bit" or platform target is set accordingly. If that is kept in mind the solution works quite nicely.
Use System.Environment.ExpandEnvironmentVariables to perform the expansion first, then pass the result to Process.Start:
System.Diagnostics.Process.Start(
System.Environment.ExpandEnvironmentVariables(#"%PROGRAMFILES%\MyApp\MyApp.exe"));
I am almost sure this does not work, however, there is an environment class in the .NET library that can return the information you are looking for.
Probably like:
// Change the directory to %WINDIR%
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir");
If you use 'programfiles' instead it might work (could not check here).
You can use
Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)`
To get the path to a special folder (in this case, 32-bit program files directory). There's more in that class that would be of help as well.
Also, I expect that Process.Start with the non-expanded path will work fine if you use UseShellExecute - the shell is capable of expanding paths on its own.
However, this is still probably a bad solution. What if the user installed your target application somewhere else? Are you sure there's no better way to get path to the application?
I'm developing a project in WinForms, and I'm on the process of creating an installer using WiX.
But when the installer is going to copy a .dll that comes from a really long path, Visual Studio says this:
'Really long route'\EnterpriseLibrary....\ is too long, the fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
I found articles that talks about MAX_PATH limitations like said in this StackOverflow question related with the Windows API.
I'm working on a big team, and we just discovered this known error, but we are not allowed to shorten or modify the path.
I tried the solution that the link above says, using the \\?\ characters before, so my WixVariables remain like this:
<?define examplesPath="\\?\$(sys.CURRENTDIR)\..\..\ExamplesFolder" ?>
That results to be something like this:
\\?\C:\reallylongpath\files
But it doesn't seem to work for WiX variables.
So my question is:
Is there any way to avoid this 260 characters limitation? If so, how?
Please, I need an answer on this!
EDIT: While I try #Jans' suggestion, I also found that, if I add the \\?\ string to my WiX variable, the error message changes. Now it says:
The system cannot find the file '\\?\Reallylongpath\..\..\andreallylongfile\'
I'm thinking that maybe the \\?\ is not converting the ..\ that I need to use... Any suggestion here?
EDIT2: I found this line at msdn:
A consequence is that \\?\ turns off file name normalization performed by Windows APIs, including removing trailing spaces, expanding ‘.’ and ‘..’
:___(
This is a terrible hack, but you could create a symlink to the real directory. A symlink is like a regular link, except for that it behaves exactly like a real directory.
Suppose you have a really long directory that causes you trouble:
C:\blahblahblah\thisisreallylong\andnotaccessible\blahblahblah\
You can create a symlink to it, that has any name you like, but is considerably shorter. Think of it as an alias. So if you call this on your console, for example in the C:\temp directory:
C:\temp\>mklink /D reallylong C:\blahblahblah\thisisreallylong\andnotaccessible\blahblahblah\
then afterwards, you can access C:\temp\reallylong as if it were your real directory. Note that you need local admin rights to create symlinks.
There are several related questions on stackoverflow but either my situation is different or I am too dumb to relate those to situation. I am hoping someone can help me with this. Further I am not even much of a .NET developer so I apologize in advance for any wrong terminology use.
My scenario is as follows: The tool that is used to deploy our .net application (One Click?) puts it in a directory whose full name exceeds 300 characters. The application uses a third party component -- lets call it dbstore -- that processes the specified file that resides in the application deployment directory.
So far we were using Assembly.GetExecutingAssembly().GetName().CodeBase to construct the fully qualified name of the file to pass to dbstore. But dbstore uses old style APIs and fails when it tries to open the file.
Since dbstore is not expected to change soon, it was recommended that the application chdir to the deployment directory and pass a relative path name in current directory to it. This is also the approach described in the accepted response PathTooLongException in C# code
However I find that Directory.SetCurrentDirectory also throws PathTooLongException. This happens even when I am using UNC path name, e.g a name starting with \\?\0000000000000\...
Am I doing something fundamentally wrong? Is there another function to use?
EDIT: It seems there is no way to achieve what I am looking for. Far as I can tell there is no way to set current directory to a long path.
Do you get a similar result when using Environment.SetCurrentDirectory() ?
If so, you may want to change your directory subfolder after subfolder.
EDIT:
Windows actually sets a limitation of 255 chars for a file path (WinXP) or 260 chars (Vista).
Note that this limitation does not apply for the filesystem, so you can have a file stored in such a long directory path, but Windows Explorer and many Windows services cannot read from such path.
Actually it seems to also include .NET framework methods since you cannot access such files. You may need to write your own filesystem API, but that's a bit too much overhead. Can't you just shorten the file path ? Does Windows offer a shortened way to address a file (like 8 octet file names) ?
Source: http://labnol.blogspot.com/2006/10/limitations-with-long-file-names-on.html