Я еще не использую их компилятор clang (длинная история), поэтому мой код не может использовать функции C++17.
(Поскольку это стандарт VCL, я считаю, что CoInitialize запускается автоматически)
Я пытаюсь создать ярлык (кнопку) для открытия «Диспетчера служб IIS» из одного из моих приложений .
Я использую код, который уже много лет работает над созданием открытых приложений, однако он не работает с:
- %windir%\ system32\inetsrv\InetMgr.exe (это взято из ярлыка инструментов администрирования)
- C:\WINDOWS\system32\inetsrv\InetMgr.exe (то же самое, без переменных)
Это код, который я использую. используя:
void __fastcall TLaunch::OpenApplication ( const AnsiString& Operation
, const AnsiString& Location
, const AnsiString& FileName
, const AnsiString& Parameters
)
{
HWND hwnd = NULL;
LPCSTR lpOperation = Operation.c_str();
LPCSTR lpFile = FileName.c_str();
LPCSTR lpParameters = Parameters.c_str();
LPCSTR lpDirectory = Location.c_str();
INT nShowCmd = SW_SHOWNORMAL;
HINSTANCE AppHandle = ShellExecuteA ( hwnd
, lpOperation
, lpFile
, lpParameters
, lpDirectory
, nShowCmd
);
INT_PTR IP_Handle = INT_PTR(AppHandle);
switch (IP_Handle)
{
case 0 : ShowMessage (L"Operating System Out of Memmory");
break;
case ERROR_FILE_NOT_FOUND : ShowMessage (L"File Not Found");
break;
case ERROR_PATH_NOT_FOUND : ShowMessage (L"Path Not Found");
break;
case ERROR_BAD_FORMAT : ShowMessage (L"The .exe file is invalid");
break;
case SE_ERR_ACCESSDENIED : ShowMessage (L"Access Denied");
break;
case SE_ERR_ASSOCINCOMPLETE : ShowMessage (L"The file name association is incomplete");
break;
case SE_ERR_DDEBUSY : ShowMessage (L"Other DDE transactions are being processed");
break;
case SE_ERR_DDEFAIL : ShowMessage (L"DDE transaction failed");
break;
case SE_ERR_DDETIMEOUT : ShowMessage (L"DDE request timed out");
break;
case SE_ERR_DLLNOTFOUND : ShowMessage (L"DLL not found");
break;
//case SE_ERR_FNF : duplicate of FILE NOT FOUND
case SE_ERR_NOASSOC : ShowMessage (L"No Application Association");
break;
case SE_ERR_OOM : ShowMessage (L"ShellExecute : Not Enough Memory");
break;
//case SE_ERR_PNF : duplicate of PATH NOT FOUND
case SE_ERR_SHARE : ShowMessage (L"ShellExecute : Sharing Violation");
break;
}
// if (IP_Handle < 32)
// {
// DWORD ShellExecuteError = GetLastError();
// ShowMessage (UnicodeString(ShellExecuteError));
// };
}
// This Returns File Not Found
OpenApplication ("open"
,"C:\\Windows\\system32\\inetsrv\\"
,"InetMgr.exe"
,""
);
// This Returns File Not Found
OpenApplication ("open"
,"C:\\Windows\\system32\\inetsrv\\"
,"C:\\Windows\\system32\\inetsrv\\InetMgr.exe"
,""
);
Когда я посмотрел на ярлык инструментов администрирования, чтобы получить сведения о файле, цель не содержала никаких кавычек или параметров, поэтому я не включил их в свой вызов.
Я также попробовал запустить C:\WINDOWS\system32\inetsrv\InetMgr.exe вручную из CMD, открытого без прав администратора. Приложение отобразилось, поэтому мне не нужно было использовать «runas». Поэтому я немного озадачен тем, почему это не работает через ShellExecuteA. (Как я уже сказал, этот код с радостью открывает другие приложения).
Может ли кто-нибудь пролить свет на то, что я делаю неправильно?
или почему это приложение ведет себя в отличие от всего остального прошу ShellExecuteA открыть?
Может??? это может быть связано с тем, почему у меня возникли проблемы с подписанием приложений с помощью ShellExecuteA?
Открытие приложения – это мой вопрос. Это просто то, что может связаны. Если для подписи приложений я использую файл Signtool.exe, установленный из MS Windows 10 SDK, мне придется использовать сценарий командной строки, аналогичный приведенному ниже
"C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe" sign /a /f "C:\Development\( RESOURCE )\_Certs\V12.pfx" /p "PasswordExample" /d "Company Name : App" /tr "http://timestamp.digicert.com" /td sha256 /fd sha256 /v "R:\(Distribute)\V12.1.1 [24-05]\(2024-05-03)\ACMS V1211.2405 (x86-Distro)\MyApp.exe"
Однако, если я запущу это с помощью ShellExecuteA, моим приложениям не будет присвоена цифровая подпись. Если вместо этого я сохраню (точный) текст, который я отправил ShellExecuteA, в пакетный файл и запущу его вручную, никаких ошибок не будет получено, и приложение получит цифровую подпись. Я озадачен.com
(Я удалил свои попытки подписать код ShellExecute много лет назад, поэтому не могу предоставить неработающие примеры)
Любая помощь которые вы можете предоставить, будут с благодарностью приняты.
С уважением

--------- 05.14.2024 -- ОБНОВЛЕНИЯ ------- --
Следуя всем отзывам (спасибо всем)
Я обновляю свой код, чтобы предоставить некоторую диагностику по запросу Реми.
HINSTANCE AppHandle = ERROR_FILE_NOT_FOUND
Я также включил GetLastError() , он начал возвращать 0 после добавления оператора переключателя, поэтому теперь он закомментирован (он возвращал 2)
Примечания:
- Я всегда использовал \ в своих строках, опубликованные мной строки пути были взяты напрямую из вывода моего отладчика. Извините, что не заметил этого.
- Это 32-разрядное приложение, поскольку я не использую расширенный компилятор clang.
- Я использую ShellExecute, потому что я не знаю ничего лучшего (и раньше это не вызывало у меня никаких проблем).
- Я посмотрю на CreateProcess чуть позже (но подозреваю, что это не поможет).< /li>
По чьему-то предложению попробовать вместо этого использовать косую черту, я сейчас это сделал. Это ничего не помогло (это тоже особенность Linux).
Я проверил это, запустив одно из своих собственных приложений, согласно моему предыдущему опыту. Это сработало без проблем.
Я добавил оператор переключения в код ответов. Он также сообщает: «Файл не найден».
Я администратор на этом компьютере. Разрешения для папки (пользователи) показывают «Чтение и выполнение» + «Список содержимого». Права доступа к файлам (пользователи) показывают «Чтение и выполнение». Я думаю, это говорит о том, что дело не в разрешениях.
UnicodeString TFile = UnicodeString(FileName);
bool found = FileExists(TFile);
if (found)
{
ShowMessage (L"Found "+TFile);
}
Я добавил приведенный выше код к предоставленному решению/функции. FileExists возвращает значение false (поэтому я думаю, что CreateProcess не поможет).
Поскольку для меня это не имеет смысла. Я задавался вопросом, связано ли это с машиной. Затем я попробовал еще раз на второй машине. Дайса все еще нет. Итак, это не работает на Win 10 и Win 2019 Server. оба полностью исправлены.
выполнить следующее (непосредственно предоставляя значения) также не удается!
HINSTANCE AppHandle = ShellExecuteA( NULL
, "open"
, "C:\\Windows\\system32\\inetsrv\\InetMgr.exe"
, ""
, ""
, SW_SHOWNORMAL
);
Спасибо всем за помощь, но, похоже, мне придется признать свое поражение

Я, скорее всего, продолжу попытки в фоновом режиме несколько разных вещей (CreateProcess и SellExecuteEx), но в конечном итоге кажется, что у этого приложения есть какое-то другое словесное свойство, которое делает его невидимым для RAD Studio

Если я найду работающее решение, я опубликую это здесь.
--------- 05.14.2024 -- ОТЗЫВ в мою сторону ---------
Поскольку я уже боролся с ShellExecuteA, я еще раз взглянул на свою проблему с цифровой подписью. Хотя мне еще не удалось подписать приложение «напрямую» с помощью ShellExecuteA, я обнаружил, что если я использую. его для запуска пакетного файла, который я создал для массового обновления некоторых файлов, я могу, по крайней мере, косвенно подписывать свои приложения
.AnsiString lpFile = "Sign All [STD] Files.bat";
AnsiString lpLocation = DestinationFolder;
AnsiString lpBatch = lpLocation + lpFile;
ShellExecuteA ( NULL // HWND hwnd
, "open" // LPCWSTR lpOperation
, lpBatch.c_str() // LPCWSTR lpFile
, "" // LPCWSTR lpParameters
, lpLocation.c_str() // LPCWSTR lpDirectory
, SW_SHOWNORMAL // INT nShowCmd
);
Подробнее здесь: https://stackoverflow.com/questions/784 ... -an-action