Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Программирование с использованием WinAPI

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

Открыть новую тему     Написать ответ в эту тему

destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Привет!
Оказывается изначально не туда написал
Теперь куда надо попал))))
 
Есть pure win32API-based прога. С главной функцией  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)  
 
к ней надо дописать функцию вызова внешнего ехе. через createprocess(....)  
Входные условия: на входе будет полный путь к ехе. Путь может содержать пробелы, не только ANSI символы - та же кирилица, к примеру.  
Затык в точке переброса параметра LPSTR pCmdLine из WinMain в api функцию createprocess на место её второго параметра LPSTR lpCommandLine или LPWSTR lpCommandLine (в зависимости от _UNICODE). КАК это сделать работоспособно вне зависимости от того - в какой раскладке будет задан путь до ехе на входе, есть/нет пробелы/китайские символы, где компилялась прога, было ли там выставлено define unicode или нет...  
 
P.S. Даже, если принудительно использовать только ANSI вариант функции и параметров - все равно getlasterror возвращает ошибку - или указанный файл не найден или синтаксическая ошибка в пути...

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 22:06 15-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child
Раз не только ANSI - забудьте про pCmdLine, юзайте GetCommandLineW(). И делайте всё в юникоде.

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 22:38 15-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
юзайте GetCommandLineW()

примеры видел, пробовал - не пашут у меня(((
 

Цитата:
И делайте всё в юникоде.

переделывать ВСЁ для этого - не в моей власти. есть тока указание кое-что поправить.
оказывается эта проблема уже давно висела на ком-то))) но так и осталась недоделанной.
и кажется я начинаю понимать - почему....

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 10:09 16-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child

Цитата:
примеры видел, пробовал - не пашут у меня(((  

А что именно не пашет? Получаете командную строку, разбираете её на составляющие через CommandLineToArgvW() и работаете с ними.

Цитата:
переделывать ВСЁ для этого - не в моей власти.

Тогда делайте в юникоде то, что обязательно должно в нём быть. С именами файлов и путями уж точно надо в юникоде работать.

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 11:19 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
А что именно не пашет?

При любом раскладе (включая и использование кода работы через CommandLineToArgvW, и использование чистого ANSI для чистого пути в ANSI символах) я получаю одно из двух:
 
getlasterror возвращает ошибку - или указанный файл не найден или синтаксическая ошибка в пути...

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 11:34 16-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child
Ну так смотрите в отладчике, что у вас там не так с путями получается. Надеюсь, не забываете, что в аргументах, полученных через CommandLineToArgvW(), первым идёт путь к самой вашей программе?

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 11:50 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ну так смотрите в отладчике

там смотреть невозможно - там рисуются наверное те самые юникодные символы, что создались в аргументах, полученных через CommandLineToArgvW().

Цитата:
первым идёт путь к самой вашей программе

да. это сделано...
хотя стоп - давайте уточним.
Есть прога Х.exe в какой-то папке на диске. Путь не важен... Изначальная. win32api-based.
Она получает на входе в параметре №1 путь до запускаемого другого ехе Y: "D:\Обработка базы\worker-debug\Y.exe"
путь получает сразу в кавычках.
Теперь для CreateProcess КАК должны выглядеть первые два параметра lpApplicationName и lpCommandLine?
 
P.S. т.е. в дебагере я вижу D:\Обработка базы\worker-debug\Y.exe вместо D:\Обработка базы\worker-debug\Y.exe
 
У меня ощущение, что получение строки из  
LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &num_args);
простым перебросом args в wstring объект - не совсем верно. походу еще надо какие-то кодировки использовать.
но какие и как определять - когда их надо, а когда не надо использовать? ...

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 12:55 16-04-2019 | Исправлено: destiny_child, 13:30 16-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child
Обычно первый параметр - "D:\Обработка базы\worker-debug\Y.exe" (без кавычек), второй - командная строка для этой самой Y.exe. Но можно оставить первый параметр пустым, а всё загнать во второй. Только в таком случае "D:\Обработка базы\worker-debug\Y.exe" надо вставлять в кавычках, потому что этот параметр парсится по пробелам. Собственно, это всё в MSDN достаточно подробно расписано.
Да, и не забывайте, что CommandLineToArgvW() аргументы выдаёт в чистом виде, уже раскавыченные.
 
Добавлено:

Цитата:
У меня ощущение, что получение строки из  
LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &num_args);
простым перебросом args в wstring объект - не совсем верно. походу еще надо какие-то кодировки использовать.

Не надо. Всё идёт в родной кодировке Windows UTF-16. CreateProcessW() ровно в ней же всё и принимает.

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 13:33 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Давайте уточним буквально
lpApplicationName = NULL;
lpCommandLine = L"\"D:\Обработка базы\worker-debug\Y.exe\""
Так?
учитывая, что по факту это значение лежит в wstring объекте, полученном после обработки  
LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &num_args);
в виде, который дебагер показывает как - D:\Обработка базы\worker-debug\Y.exe
 
Если везде ответ ДА - то тогда я безусловно ничего не понимаю, т.к. этот код не работает. Системе не удается найти указанный файл... Но файл 100% есть и лежит по указанному пути...  
Так что либо где-то unicode-utf8-utf16-ansi-ХЗ-что-ещё не конвертится, или кодировка исходников неверная))), либо какие опции сборки надо доп.определить...
 
https://habr.com/ru/sandbox/43899/ к примеру пишет про кодировки....

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 14:23 16-04-2019 | Исправлено: destiny_child, 14:26 16-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child

Цитата:
Так?

Да. Если задать это значение вручную, работает?

Цитата:
Если везде ответ ДА - то тогда я безусловно ничего не понимаю, т.к. этот код не работает.

Закавычить args[1] перед передачей его в CreateProcessW() не забываете? Если не закавычить, работать не будет - распадётся на два аргумента по пробелу.

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 14:32 16-04-2019
MERCURY127



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Попробуй для начала без кириллицы...
 
Добавлено:
Ну и PathQuoteSpacesW использовать

Всего записей: 11554 | Зарегистр. 03-08-2008 | Отправлено: 14:32 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Если задать это значение вручную, работает?

"Запрошенная операция требует повышения"
И еще - значение переменной в дебагере при ручной установке значения в коде напрямую выглядит ровно и красиво: "D:\Обработка базы\worker-debug\Y.exe"
т.е. когда мы получаем и обрабатываем LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &num_args); выходит мы все же что-то не доделываем до конца.
Раз получаем мусор какой-то /браб/, явно видимый в дебагере.
 

Цитата:
Закавычить args[1] перед передачей его в CreateProcessW() не забываете?

Еще больше кавычек?
"D:\Обработка базы\worker-debug\Y.exe" - вот ровно так видится эта строка для переменной lpCommandLine, если я её в коде изначально устанавливаю, а не из распарсенных параметров CommandLineToArgvW собираю... "D:\Обработка базы\worker-debug\Y.exe" - вот так, если из параметров собирать. Кавычки есть, как мы видим. Или их еще больше надо?
 

Цитата:
Ну и PathQuoteSpacesW использовать

дык вроде больше кавычек. чем их есть в строке и не надо...

Цитата:
Попробуй для начала без кириллицы...

сработало - в том смысле, что результат такой же как и при:

Цитата:
Если задать это значение вручную, работает?

"Запрошенная операция требует повышения"
 
НО в любом раскладе с повышением надо то, чтоб ЛЮБЫЕ кодировки входные принимались. Что японец вставит путь, что монгол, что германец...
 

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 15:26 16-04-2019 | Исправлено: destiny_child, 15:30 16-04-2019
Abs62



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
destiny_child
Тогда надо смотреть, как и в какой кодировке тут передаётся программе командная строка. Потому что её переводом в родной UTF-16, который потом и извлекается GetCommandLineW(), занимается система.
 
Кстати, а почему у вас в "LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &num_args);" GetCommandLine() без "W"? Собираете программу как юникодную?

----------
0 программистов ругал сердитый шеф
Потом уволил одного, и стало их FF

Всего записей: 6080 | Зарегистр. 22-10-2005 | Отправлено: 16:10 16-04-2019
MERCURY127



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
какая версия винды? отладчик? компилятор?  
какая дефолтная неуникодная кодировка в системе? а в консоли?  
 
Добавлено:

Цитата:
дык вроде больше кавычек. чем их есть в строке и не надо...  
больше не надо, но и меньше - тоже.  
 
пока я вижу лишь, что у тебя строки больше на утф8 смахивают, чем на утф16.
 
утф8 для винды совершенно ЧУЖОЙ, ВРЕДНЫЙ И ОПАСНЫЙ.  
никаких утф8 под виндой даже не пытайся делать.

Всего записей: 11554 | Зарегистр. 03-08-2008 | Отправлено: 16:12 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
GetCommandLine() без "W"

потеряшка-буква УЖЕ после написания поста была вставлена. просто пост не редактировал.

Цитата:
Собираете программу как юникодную

DEFINE += _UNICODE UNICODE  
стоят обе версии. об этом же речь?
 

Цитата:
какая версия винды? отладчик? компилятор?   какая дефолтная неуникодная кодировка в системе? а в консоли?  

win10 x64 RUS
gdb 7.11.1 ABI x32
gcc 5.4.0 ABI x32
на основе пакета mingw-w64 под х86
пакет собирается в среде Qt Creator'a. Да, проект изначально мультиплатформенным был. Систему Сборки под него создавали, ковыряли и перебирали руками для того, чтоб всё - даже для native win32 - собиралось из под оупенсорсных компонентов. Хотя бы и с кучей ifdefine. И вот это легаси приплыло в руки....
"дефолтная неуникодная кодировка" = 'Россия' я так понимаю. Мы же про Панель Управления - Язык - Регион - Дополнительно сейчас разговариваем?
Консоль - 866 имхо, кто ж ее править-то будет на другую...
 
Да, я согласен, что строка ползёт в виде UTF-8 - знакомые крякозябры. Но не может же QtCreator так тупо конвертить при передаче в дебаггер то, что я в простейшем editbox'e CmdArgs этой среды вставил в чистом СР1251 виде - полный путь до ехе в кавычках...
 
И безотносительно к тому, что вы вероятно можете написать про неподходящий инструментарий и т.п.
""Запрошенная операция требует повышения"" - эта ошибка понятно дело лечится RunAS от лица админа. НО - у меня на диске куча устаревших прог, которые создают вызовы внешних утилит - и они не требуют повышения привилегий. И их код был явно написан еще аж до рождения вин7 - но работают же до сих пор. И сомневаюсь, что они что-то кроме CreateProcess(...) вызывали....
Что же не такого в CreateProcess(...) - что она не срабатывает так же просто - как и выглядит...
Что по этому поводу можно попробовать сделать?
 
 
P.S. пересобрать под чистой студией проект я попробую - дома, в частном порядке. может это реально даст какое другое поведение. Но вот "Запрошенная операция требует повышения" - всё равно это что-то с чем-то на данный момент времени.

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 18:48 16-04-2019
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Это отладчик скорее всего требует права админа.

Всего записей: 1530 | Зарегистр. 01-11-2004 | Отправлено: 19:49 16-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Это отладчик скорее всего требует права админа.

я пробовал запускать и уже готовый релиз. ошибка такая же.

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 22:38 16-04-2019
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Какой requestedExecutionLevel в Manifest'е ? Если он есть, конечно.

Всего записей: 1530 | Зарегистр. 01-11-2004 | Отправлено: 07:52 17-04-2019
destiny_child



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Какой requestedExecutionLevel в Manifest'е ? Если он есть, конечно.

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

Всего записей: 3306 | Зарегистр. 01-04-2006 | Отправлено: 10:17 17-04-2019
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Он для разных целей может подходить.
Мне, например, понадобился

Код:
 
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>
 

 
Чтобы права админа просил при запуске, будет

Код:
 
...
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
...
 

 
А про этот конкретный случай без просмотра кода трудно советы давать.
Настораживает сам Qt - это та ещё гадость.
 

Всего записей: 1530 | Зарегистр. 01-11-2004 | Отправлено: 17:01 17-04-2019
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Программирование с использованием WinAPI


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru