Ярлык Windows для символической ссылки на исполняемый файл

Я собираюсь использовать проблему, которая у меня возникла с приложением Java, чтобы объяснить мой вопрос на примере, но этот вопрос не имеет ничего общего с Java.

Я использую Windows 7 (64-разрядную версию) и хочу создать ярлык в меню «Пуск» для запуска приложения Java с графическим интерфейсом. Начиная с Java 8, установщик помещает символические ссылки NTFS в хорошо известное место, указывающие на конкретный выпуск (т.е. подверженный частым изменениям) каталог:

C:\>where javaw
C:\ProgramData\Oracle\Java\javapath\javaw.exe

C:\>dir C:\ProgramData\Oracle\Java\javapath\javaw.exe
 Volume in drive C is OS
 Volume Serial Number is D4DC-33AF

 Directory of C:\ProgramData\Oracle\Java\javapath

05/03/2015  15:40    <SYMLINK>      javaw.exe [C:\Program Files\Java\jre1.8.0_40\bin\javaw.exe]

Я создал ярлык, целевая командная строка которого была C:\ProgramData\Oracle\Java\javapath\javaw.exe java_app.jar, но когда я запускаю его, Windows говорит, что путь javaw.exe не существует. Я могу успешно запустить ту же командную строку из диалогового окна «Выполнить» Windows; только не с ярлыка. Кто-нибудь может предложить решение? (Я предпочитаю не создавать пакетный файл для запуска команды, так как это создаст бесполезную консольную коробку.)

(Примечание. Вы также можете увидеть ту же проблему без использования Java. Просто создайте символическую ссылку на Notepad.exe (используя команду MKLINK), а затем попробуйте создать ярлык для символической ссылки.)


person Klitos Kyriacou    schedule 06.03.2015    source источник
comment
Просто ярлыки? Двойной щелчок напрямую никогда не работал у меня, по крайней мере, не в Vista или Windows 7. Это что-то странное с тем, как ShellExecute API вызывается Explorer и др. В качестве обходного пути вы можете создать неконсольную программу запуска, которая вызывает CreateProcess и завершает работу.   -  person Eryk Sun    schedule 06.03.2015
comment
Спасибо, eryksun, это хорошая мысль о том, что у двойного щелчка тоже есть эта проблема. Как ни странно, запуск той же символической ссылки из окна «Выполнить» Windows работает нормально, хотя это также работает и в проводнике. Ваше предложение написать лаунчер, пожалуй, лучшее решение.   -  person Klitos Kyriacou    schedule 07.03.2015
comment
Это было решено? У меня была точно такая же проблема в прошлом году, и у меня ее нет. Я не знаю точно, что изменилось, как я это исправил, или это было исправлено конкретным Центром обновления Windows. Но я могу использовать ярлык `C:\ProgramData\Oracle\Java\javapath\javaw.exe -Xmx1G -jar C:\Program Files\MyApp\myapp.jar. Я создал ярлык на рабочем столе, а затем прикрепил его к панели задач. После каждого обновления символическая ссылка изменяется установщиком Java, и мне приходится вручную заново создавать ярлык. Его нельзя обновить, потому что путь не изменился, иначе он не будет работать.   -  person    schedule 22.10.2016
comment
@user314159 user314159: проблема всегда была прерывистой - ярлык для символической ссылки работал иногда, но не всегда.   -  person Harry Johnston    schedule 22.10.2016


Ответы (2)


Вы все еще можете сделать бесполезный пакетный файл. Используйте ЗВОНОК внутри него, чтобы окно консоли закрывалось сразу после запуска вашего приложения.

Кроме того, сейчас нет на компьютере с Windows, но вы можете вместо этого создать ярлык для CMD.exe и передать туда свою команду? Вы можете сделать это вместе с CALL в случае появления окна консоли.

person dimoniy    schedule 06.03.2015
comment
Спасибо димоний. Я думаю, вы имеете в виду START (CALL для вызова пакетных файлов). Командная строка cmd /c start javaw ... с ярлыком, настроенным для запуска в свернутом окне, является разумным компромиссом, хотя жаль, что она вообще должна создавать окно. - person Klitos Kyriacou; 07.03.2015

Этот простой лаунчер может быть полезен; вы можете создать для него один или несколько ярлыков с теми же параметрами командной строки, которые вы использовали бы в ярлыке для javaw.exe.

#include <Windows.h>

void NoCRTMain(void)
{
    wchar_t * cmdline = GetCommandLineW();
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    GetStartupInfo(&si);

    if (!CreateProcess(L"C:\\ProgramData\\Oracle\\Java\\javapath\\javaw.exe", cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    {
        MessageBox(NULL, L"Unable to launch Java.", L"runjava.exe", MB_OK);
    }

    ExitProcess(0);
}

Для компиляции в Visual Studio потребуется изменить некоторые настройки проекта:

  • Проверка безопасности буфера на «Нет» при генерации кода C/C++
  • Игнорировать все библиотеки по умолчанию на «Да» во входных данных компоновщика
  • Точка входа в NoCRTMain в расширенном компоновщике
  • /DYNAMICBASE:NO и /FIXED:YES как обсуждалось здесь

(Или вы можете изменить основную функцию с NoCRTMain на WinMain, но тогда вам нужно установить среду выполнения C или связать ее статически.)

Очевидно, вы можете легко изменить код для запуска символических ссылок, отличных от javaw.exe, хотя некоторым программам может не понравиться тот факт, что argv[0] не указывает на собственный исполняемый файл приложения.

person Harry Johnston    schedule 15.03.2015