David Arno
David Arno

Reputation: 43254

How do I create a symlink in Windows Vista?

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.

Upvotes: 6

Views: 3328

Answers (3)

mdb
mdb

Reputation: 52819

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...

Upvotes: 10

Scott James
Scott James

Reputation: 684

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.

Upvotes: 4

RB.
RB.

Reputation: 37172

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

Upvotes: 3

Related Questions