How do I create a symlink in Windows Vista?
Asked Answered
S

3

6

I am looking to create symlinks (soft links) from Java on a Windows Vista/ 2008 machine. I'm happy with the idea that I need to call out to the JNI to do this. I am after help on the actual C code though. What is the appropriate system call to create the link? Pointers to some good documentation on this subject would be very much appreciated.

Shipentine answered 13/10, 2008 at 12:22 Comment(0)
L
10

Symbolic links in Windows are created using the CreateSymbolicLink API Function, which takes parameters very similar to the command line arguments accepted by the Mklink command line utility.

Assuming you're correctly referencing the JNI and Win32 SDK headers, your code could thus be as simple as:

JNIEXPORT jboolean JNICALL Java_ClassName_MethodName
    (JNIEnv *env, jstring symLinkName, jstring targetName)
{
    const char *nativeSymLinkName = env->GetStringUTFChars(symLinkName, 0);
    const char *nativeTargetName = env->GetStringUTFChars(targetName, 0);

    jboolean success = (CreateSymbolicLink(nativeSymLinkName, nativeTargetName, 0) != 0);

    env->ReleaseStringUTFChars(symLinkName, nativeSymLinkName);
    env->ReleaseStringUTFChars(targetName, nativeTargetName);

    return success;
}

Note that this is just off the top of my head, and I haven't dealt with JNI in ages, so I may have overlooked some of the finer points of making this work...

Lions answered 13/10, 2008 at 12:38 Comment(0)
P
4

This has been on my list to try, from my notes:

The API:

http://msdn.microsoft.com/en-us/library/aa363866(VS.85).aspx

BOOLEAN WINAPI CreateSymbolicLink(
  __in  LPTSTR lpSymlinkFileName,
  __in  LPTSTR lpTargetFileName,
  __in  DWORD dwFlags
);

Some C# examples:

http://community.bartdesmet.net/blogs/bart/archive/2006/10/24/Windows-Vista-2D00-Creating-symbolic-links-with-C_2300_.aspx

A C++ Example, this is cnp from another article I was reading. I have not tested it so use it with caution.

typedef BOOL (WINAPI* CreateSymbolicLinkProc) (LPCSTR, LPCSTR, DWORD);

void main(int argc, char *argv[]) 
{
  HMODULE h;
  CreateSymbolicLinkProc CreateSymbolicLink_func;
  LPCSTR link = argv[1];
  LPCSTR target = argv[2];
  DWORD flags = 0;

  h = LoadLibrary("kernel32");
  CreateSymbolicLink_func =
    (CreateSymbolicLinkProc)GetProcAddress(h,
  if (CreateSymbolicLink_func == NULL) 
  {
     fprintf(stderr, "CreateSymbolicLinkA not available\n");
  } else 
  {
     if ((*CreateSymbolicLink_func)(link, target, flags) == 0) 
     {
        fprintf(stderr, "CreateSymbolicLink failed: %d\n",
        GetLastError());

  } else 
  {
     printf("Symbolic link created.");
  }
}

}

Having said this, I would not use this code :-) I would either be inclined to fork mklink or look at the native library from jruby/jpython (Sorry I cant look it up atm as my network connection is flakey). I seem to recall that jruby has written a library that wraps up various posix apis into java (thinks like chown that are required for ruby compliance but are not cross platform). This library is being used by the jpython folks who seem very pleased with it. I would be surprised if this library does not offer sym link support.

Pressure answered 13/10, 2008 at 12:34 Comment(0)
T
3

Couldn't you just call out to the command line and use mklink?

Thant answered 13/10, 2008 at 12:23 Comment(5)
No! I wish to use the appropriate C/C++ call directly.Shipentine
Fair enough. Is there any specific reason though? I mean, are there features you require that are not available through mklink, or similar?Thant
I mentioned it as an option, its a sensible choice but you do pay an overhead for the process creation.Pressure
I already have a JNI dll that I need to extend. So just calling the API is far more desirable than spawning a new process to call a separate app, worrying about the path to that app, capturing its return code to know if creation occurred etc.Shipentine
Upon reflection I've changed my down vote to an up vote. I may not want to do it that way, but it isn't a wrong answer and may be useful to others.Shipentine

© 2022 - 2024 — McMap. All rights reserved.