Как создать символическую ссылку в Windows Vista?

#c #c #windows #java-native-interface #symlink

Вопрос:

Я ищу возможность создания символических ссылок (мягких ссылок) из Java на компьютере с Windows Vista/ 2008. Я доволен идеей, что для этого мне нужно обратиться к JNI. Однако мне нужна помощь по фактическому коду C. Каков соответствующий системный вызов для создания ссылки? Мы были бы очень признательны за ссылки на хорошую документацию по этому вопросу.

Ответ №1:

Символические ссылки в Windows создаются с помощью функции API CreateSymbolicLink, которая принимает параметры, очень похожие на аргументы командной строки, принятые утилитой командной строки Mklink.

Предполагая, что вы правильно ссылаетесь на заголовки JNI и Win32 SDK, ваш код, таким образом, может быть таким же простым, как:

 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;
}
 

Обратите внимание, что это просто не укладывается у меня в голове, и я уже целую вечность не имел дела с JNI, поэтому, возможно, я упустил некоторые тонкости этой работы…

Ответ №2:

Это было в моем списке, чтобы попробовать, из моих заметок:

API:

http://msdn.microsoft.com/en-us/library/aa363866(ПРОТИВ 85).aspx

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

Некоторые примеры C# :

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

Пример C , это cnp из другой статьи, которую я читал. Я не тестировал его, поэтому используйте его с осторожностью.

 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 availablen");
  } else 
  {
     if ((*CreateSymbolicLink_func)(link, target, flags) == 0) 
     {
        fprintf(stderr, "CreateSymbolicLink failed: %dn",
        GetLastError());

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

}

Сказав это, я бы не стал использовать этот код 🙂 Я бы либо был склонен к развилке mklink, либо посмотрел на родную библиотеку из jruby/jpython (извините, я не могу найти ее в банкомате, так как мое сетевое подключение слабое). Я, кажется, припоминаю, что jruby написал библиотеку, которая объединяет различные API posix в java (думает, как chown, которые необходимы для соответствия требованиям ruby, но не являются кроссплатформенными). Этой библиотекой пользуются люди из jpython, которые, похоже, очень довольны ею. Я был бы удивлен, если бы эта библиотека не предлагала поддержку sim — ссылок.

Ответ №3:

Не могли бы вы просто вызвать командную строку и использовать mklink?

Комментарии:

1. Нет! Я хочу использовать соответствующий вызов C/C напрямую.

2. Справедливо. Но есть ли какая-то конкретная причина? Я имею в виду, есть ли необходимые вам функции, которые недоступны через mklink или аналогичные?

3. Я упомянул об этом как о варианте, это разумный выбор, но вы платите накладные расходы за создание процесса.

4. У меня уже есть библиотека JNI, которую мне нужно расширить. Поэтому просто вызвать API гораздо более желательно, чем создавать новый процесс для вызова отдельного приложения, беспокоиться о пути к этому приложению, записывать его код возврата, чтобы узнать, произошло ли создание и т. Д.

5. Поразмыслив, я изменил свой голос «против» на «против». Возможно, я не хочу делать это таким образом, но это не неправильный ответ и может быть полезен другим.