Win32API function to join directories? - c

Does the Win32 API have a function for joining two paths?
I can't find it, so I thought I'd ask before rolling my own.

Maybe you want the functionality of PathCombine from Shell Path Handling Functions.

I'm not sure what you mean by joining two paths, but you can use CreateSymbolicLink to link one directory to another. Another option is CreateHardLink which is a way to gives files more than one name. There are also junctions available which are yet another way to link directories.
Note that all of these are yet different from the more user-friendly shortcut (*.lnk) files that get interpreted by the shell.
If you don't have to do this from code, use SysInternals' (now Microsoft's) Junction utility.

Related

MoveFile and MoveFileEx works weird if filenames are the same in DOS 8.3 style

Ok, I have files named
ANIME~1.MKV~FNH47B97
ANIME~1.MKV
It is FULL filenames. It is named so by user.
And I want to rename the first one to ANIME~1.JPG. From OS point of view they seem to be the same files. And both MoveFile and MoveFileEx do nothing. They return OK and that's all.
Another weird situation is when we have, for example,
ANIME~2.MKV~FNH47B97
ANIME~3.MKV
And I want to rename the first one to ANIME~2.MKV
OS founds that it's the same as ANIME~3.MKV and still does nothing.
It depends on the number of files with "the same dos 8.3 names" in the folder
Any way to workaround it? May be some additional actions/flags needed?
To summarise the discussion in the comments as an approximate answer: MoveFile(Ex) works on the full filenames, though it can find the source file by its short name, the destination file is taken to be the long name.
This means that the destination filename should not clash with any long or short filenames of existing files. This is probably why your second test-case fails.
The first test-case probably fails for a similar reason; I've tried it with just those two files and MoveFile works with it.
It is possible to disable the generation of DOS style 8.3 shortnames, see KB121007, but I really don't recommend it. It can cause lots of issues, see for instance this article. Also, this is a decision that should be left to the system administrator, not any application.

Is there a quick file open/find like IntelliJ's find file, or Sublime's? Something with fuzzy search. But in Emacs?

I'm looking for something that's a bit robust in how it finds files in Emacs. I have a project made up a number of different files, and a lot of them. So, I think maybe Emacs would need to cache a lookup or something like that to make a quick find/open facility to work. It would need to also be configured per project to consider only some directories and exclude others inside of this project, since a number of files and directories are generated and hold a massive amount of text and sometimes a concatenated representation of the rest of the code.
Is there a quick file open/find like IntelliJ's find file, or Sublime's? Something with fuzzy search. But in Emacs? That could help with this problem?
Projectile can probably do what you're after. It describes itself as a "project interaction library" with facilities for finding project files quickly.
Try projectile: https://github.com/bbatsov/projectile (see its fancy UI, helm-projectile). You'll have the command projectile-find-file. It is based on projects (they are defined by a .git/.gh/… or a .projectile).
permanent caching ? Yes
filter out directories ? Yes (with a command or a config into the .projectile)
fuzzy search ? Yes, a few: emacs'default, ido, ido-fuzzy, grizzl or helm.
you install it simply with M-x package-install RET projectile RET.
See this EmacsWiki page, which is is a jumping-off place for multiple answers to your question.
Emacs has a built-in file-name cache -- see (emacs) File Name Cache and this page.
See also Emacs bookmarks, and in particular, Bookmark+. You can bookmark any file or set of files. You can bookmark a Dired buffer, including its omit set, markings, and included subdirs. You can bookmark a set of such Dired buffers. You can aggregate bookmarks and use them to perform actions that set up environments etc. They can be triggered in various ways. You can bookmark Emacs desktops. You can tag bookmarks and files & dirs with free-form tags, which lets you organize them flexibly into overlapping sets.
See also this page about project support with Icicles.

How to achieve symbol referencing across directories in vim?

Can ctags tag symbols from a directory up in the hierarchy also or is it limited to create tags for current and sub-directories only?
Basically I'm looking for Visual Studio like symbol cross referencing it is very helpful in understanding alien source code flow.
If not Vim, then which other editor should I use?
thanks
Ctags only recurses to subdirectories. But all you have to do is run ctags -R . in your project home directory, and it will create a tags file for your whole project.
You aren't limited to specifying one tags file in Vim. This is an alternative to the other answers; you can just do something like:
set tags=tags,~/wintags,c:/path/to/moretags/etc
So you don't need to take the time regenerating a monolithic tags file when you just want to update your local tags.
Regarding the OP's comment in another answer,
yes thats correct but when i open a file say proj/dir1/def.c and press ctrl+] on a function name which is defined say in proj/dir2/abc.c, I get tag not found :(
You could also create one tags file for all of your projects at the 'proj' root:
set tags=tags;c:/path/to/proj
This will use the first file named tags that it finds as it walks up the directory hierarchy from where you are.
You can combine these two techniques to have a project-local tags file and then a "global" tags file that isn't updated as often.
Whilst it's got similar user interface for asking it to do it's thing, so you need to actually specify "go down directories", I find that cscope is a very nice tool, whcih does everything that ctags does and a bit more.
ctags (well, exctags at least) can create tags for as many directory trees you want. Simply run
exctags -R dir1 dir2 ...
Then vim knows about all the symbols you need. For example, one of the directories could be /usr/include in addition to your own source directory.
Make sure to run vim path/to/file.c from the same directory you created the tags file in.

Creating a unique temporary directory from pure C in windows

I'd like to create a unique temporary directory in Windows from some C
code (not C++ or C#). I want to do this so that I can put some temp
files in the directory, and then delete them all easily when I'm done
(by removing the directory recursively).
I'm essentially looking for an equivalent of the linux
mkdtemp
function. There is a C# answer here, and responses on this
question
suggest using Boost. But since I'm using C, those solutions don't work
for me.
The best I've been able to come up with so far is to use
GetTempFileName
followed by CreateDirectory,
but the problem there is that if I ask
GetTempFileName
to create a unique file name, it will also create the file (which I
don't want, since I want to make a directory instead).
Relatedly, there's
GetTempPath,
which returns the location of the user's temp folder from environment
variables - but since I want to create my own directory that I can
safely delete later, I still need to create a directory inside any
path it would return.
It looks like if I want a unique directory to be created, I'll have to
create a temp file, get the name, delete it, and then create a
directory with the same name - which sounds very messy.
Any other ideas?
You can use what GetTempPath returns concatenated with a Guid to ensure uniqueness of the directory. You can create a Guid using UuidCreate or CoCreateGuid Function.
To delete recursively the directory, there is an example here in pure C: How to remove directory recursively? based on FindFirstFile, FindNextFile, DeleteFile and RemoveDirectory.
There is also SHFileOperation but it's more heavyweight and is based on the Windows Shell functions, and the Shell DLLs are not always wanted, especially if you're writing server code.
Use GetTempPath then CreateDirectory with a random name under it, optionally retrying if CreateDirectory fails due to it already existing. But if your name generation is good enough, the likelihood of a collision with an existing name is much smaller than the likelihood of a blackhat guessing your password or even your private key, so you might as well ignore it.
Use _tempnam tmpnam_s to create a filename that doesn't exist yet, and then use CreateDirectory to create the directory. There's technically a race condition if you do this, in that another process could potentially create a file or directory with that name in the time in between when you generate the filename and when you create the directory, but the odds of that are rather unlikely. To protect against that, you can loop until you succeed.
For recursively removing a directory tree, you can use SHFileOperation. Alternatively, you can do the directory traversal yourself with FindFirstFile/FindNextFile, DeleteFile, and RemoveDirectory.
If you want to remove the directory automatically upon exiting, register a function using atexit. This will only work for normal program termination (i.e. via the exit function or via returning from main/WinMain). This will not work for abnormal program termination (e.g. via abort, an access violation, someone else calling TerminateProcess, etc.).

Delete all files from pendrive using C program

I am searching for a solution to delete all files from my pendrive using a C program. I don't want the code to detect the pendrive as that's not a concern right now. I would appreciate any links that could help me out on this.
Note: I am working on Windows 7 64-bit and I want to delete the entire contents from my pendrive, which contains .exes and .dlls.
Thanks and Regards,
Radix
The non-hack correct way to do this, is via the Virtual Disk Service.
If you can't use something like rm -rf F:\* and you really do need to implement it yourself in C then I think I'd probably opt for a recursive solution based on FindFirstFile and FindNextFile. These are the native Windows APIs for enumerating directories. Not remotely portable, but it doesn't seem that's a requirement.
Basically the idea is that you write a function, EmptyDir(), say, whose job it is to delete the contents of a directory. The function uses FindFirstFile and FindNextFile to walk the contents of the directory. When a file is encountered it is deleted. When a directory is encountered, EmptyDir() is called recursively. The last job of EmptyDir(), before it returns, is to delete the now empty directory.

Resources