Как программно (C++) запустить приложение из ярлыка Windows (файл .lnk)?

как программно запустить приложение из ярлыка Windows (файл .lnk)?

Я попытался использовать API ShellExecute, и, похоже, он работает. Любое предостережение?

Спасибо.

Вот фрагмент моего текущего кода:

#include <windows.h>

#include <map>
#include <string>
#include <iostream>

int main( int, char** )
{
   std::map< int, std::wstring > errors;
   errors[0]                      = L"The operating system is out of memory or resources.";
   errors[ERROR_FILE_NOT_FOUND]   = L"The specified file was not found."; 
   errors[ERROR_PATH_NOT_FOUND]   = L"The specified path was not found."; 
   errors[ERROR_BAD_FORMAT]       = L"The .exe file is invalid (non-Microsoft Win32 .exe or error in .exe image).";
   errors[SE_ERR_ACCESSDENIED]    = L"The operating system denied access to the specified file.";
   errors[SE_ERR_ASSOCINCOMPLETE] = L"The file name association is incomplete or invalid.";
   errors[SE_ERR_DDEBUSY]         = L"The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed.";
   errors[SE_ERR_DDEFAIL]         = L"The DDE transaction failed.";
   errors[SE_ERR_DDETIMEOUT]      = L"The DDE transaction could not be completed because the request timed out.";
   errors[SE_ERR_DLLNOTFOUND]     = L"The specified DLL was not found.";
   errors[SE_ERR_FNF]             = L"The specified file was not found.";
   errors[SE_ERR_NOASSOC]         = L"There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable.";
   errors[SE_ERR_OOM]             = L"There was not enough memory to complete the operation.";
   errors[SE_ERR_PNF]             = L"The specified path was not found.";
   errors[SE_ERR_SHARE]           = L"A sharing violation occurred.";

   int ret = reinterpret_cast< int >( ::ShellExecute(0,L"open",L"\"C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\Accessories\\Calculator.lnk\"",0,0,SW_SHOW) );
   const int minimumRetOK = 33;
   if ( ret < minimumRetOK ) {
      if ( errors.count( ret ) ) {
         std::wcout << L"Error " << ret << L" " << errors[ ret ];
      } else {
         std::wcout << L"Error " << ret << L" undocumented error";
      }
   }

    return 0;
}

person Alessandro Jacopson    schedule 10.12.2010    source источник


Ответы (3)


Я не уверен, в чем вы не уверены, вы наблюдаете поведение задокументировано.

Операция «открыть» ShellExecute будет делать все, что делает оболочка, когда вы «открываете» файл, на который ссылается аргумент файла (вы можете щелкнуть правой кнопкой мыши ярлык и явно выбрать «Открыть», но это также операция по умолчанию для .lnk , то же самое, что и двойной щелчок).

«Открывая» файл быстрого доступа, он «открывает» цель, если цель является исполняемым файлом, он будет запущен, если это документ или файл данных, он откроется в связанной программе или запросит программу, если нет связанные.

person Clifford    schedule 10.12.2010
comment
Спасибо за ваше объяснение. - person Alessandro Jacopson; 10.12.2010

ShellExecute или CreateProcess должны иметь возможность открыть файл ссылки. Если они не могут найти связанный файл и/или программу, вы всегда можете использовать этот API и делегировать тяжелую работу «cmd start» или «explorer». Например. ShellExecute(0, "open", "explorer", linkfile, 0, SW_SHOW);

person Gene Bushuyev    schedule 10.12.2010
comment
Я всегда думал, что CreateProcess не может открывать файлы ссылок (только исполняемые файлы), для них вам нужна оболочка (например, ShellExecute) - person Ben; 22.10.2019

ShellExecute должно работать.

Но, ...

int main( int, wchar_t* )

... ни один известный мне компилятор не поддерживает эту подпись. Просто пиши:

int main()

Кроме того, для диагностических сообщений просто используйте функцию FormatMessage Windows API или, если код предназначен исключительно для Visual C++, используйте соответствующий класс поддержки, связанный с этим компилятором.

Ура и чт.,

person Cheers and hth. - Alf    schedule 10.12.2010
comment
Да, я ошибся в основной подписи. Компилятор Microsoft позволяет мне это сделать :-) Что касается FormatMessage, я знаю об этом, но я думаю, что в этом случае это не сработает, потому что ShellExecute имеет свои коды ошибок. - person Alessandro Jacopson; 10.12.2010
comment
@uvts_cvs: ну, я не могу найти DLL ресурса сообщений для shell32, поэтому FormatMessage будет работать только для трех кодов ERROR_*xxx*. :-( - person Cheers and hth. - Alf; 11.12.2010