Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблемы с CreateProcess при запуске из-под Win службы / 25 сообщений из 30, страница 1 из 2
27.02.2017, 15:52
    #39411021
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Есть служба "Сетевая служба" (Fax).
При старте она запускает функцию из dll
В эту ф-цию я вставил код:
Код: plaintext
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.
static DWORD  DEVICE_LIMIT;
...

       //----вычисление DEVICE_LIMIT----
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
        ZeroMemory(&pi, sizeof(pi));
        WriteDebugString(L"   Proga.exe before start.\r\n");
        // Start the shelled application:
        if (CreateProcess(NULL, L"Proga.exe", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
         WriteDebugString(L"   Proga.exe started.\r\n");
          // Wait for the shelled application to finish:
          WaitForSingleObject(pi.hProcess, INFINITE);
          DEVICE_LIMIT = 3;
          //GetExitCodeProcess(pi.hProcess, &DEVICE_LIMIT);
          CloseHandle(pi.hProcess);
        } else {
          WriteDebugString(L"   Proga.exe NOT started.\r\n");
          DEVICE_LIMIT = 0;
        }
        WriteDebugString(L"   DEVICE_LIMIT=%d\r\n", DEVICE_LIMIT);
        //----вычисление DEVICE_LIMIT----



Так вот он вылетает очевидно на CreateProcess.
Не удалось запустить службу на Локальный компьютер
Ошибка 1067: процесс был неожиданно завершен
А в логе видим:
02.27.2017@15:17:25.919: Proga.exe before start.
и на этом обрывается
что подтверждает вылет именно на CreateProcess, и именно вылет а не FALSE.

Что еще:
Аналогичный API код в VB.Net с этой же proga.exe под юзер-аккаунтом работает на ура (в том числе если компилировать VB под x64, притом что proga.exe строго Win32).
Код: vbnet
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.
    Dim path As String = "Proga.exe"
    MsgBox(GetExitCodeAPI(path))

  Public Function GetExitCodeAPI(ByVal FilePath As String) As Integer
    Dim proc As PROCESS_INFORMATION
    Dim start As New STARTUPINFO
    Dim bRet As Boolean
    Dim sa As SECURITY_ATTRIBUTES

    start.cb = Marshal.SizeOf(start)
    start.dwFlags = STARTF_USESHOWWINDOW
    start.wShowWindow = SW_HIDE
    ' Start the shelled application:
    'bRet = CreateProcess(vbNullString, FilePath, sa, sa, True, NORMAL_PRIORITY_CLASS, IntPtr.Zero, IO.Path.GetDirectoryName(FilePath), start, proc)
    bRet = CreateProcess(vbNullString, FilePath, sa, sa, True, NORMAL_PRIORITY_CLASS, IntPtr.Zero, vbNullString, start, proc)
    If bRet Then
      ' Wait for the shelled application to finish:
      WaitForSingleObject(proc.hProcess, INFINITE)
      Dim lpExiteCode As Integer = 0
      GetExitCodeProcess(proc.hProcess, lpExiteCode)
      CloseHandle(proc.hProcess)
      Return lpExiteCode
    End If
    Return 0
  End Function



Еще могу сказать что Proga.exe 32-бит (здесь по другому никак)
Сама dll (а также успешный тест на VB.Net) - 64-бит
Смысл задачи - получить GetExitCodeProcess(Proga.exe 32-бит ),
через dll не получится именно по причине что интересующийся процесс может быть 64 бит, а dll/exe поставляющий информацию (число) строго 32-бит.

Вот я не могу понять, что происходит с CreateProcess при вызове из dll-ф-ции, но очевидно что-то не то.
Могу еще конечно сделать тоже самое через ShellExecuteEx, но это по сути зеркало того же кода.

Глобальная задача в чем.
Число девайсов DEVICE_LIMIT -следует из "лицензии", а лицензия - это AsProtect который в моем случае 32-битный и точка.
Это число надо как-то вычислить и передать в ф-цию dll (может быть 64-битной) при ее вызове.
...
Рейтинг: 0 / 0
27.02.2017, 17:12
    #39411090
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
У меня заработал код с ShellExecuteEx
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
       //----вычисление DEVICE_LIMIT----
        SHELLEXECUTEINFO ExecInfo;
        ZeroMemory(&ExecInfo, sizeof(ExecInfo));
        // Set up the structure.
        ExecInfo.cbSize = sizeof(ExecInfo);
        ExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ExecInfo.lpFile = L"C:\\Setup\\FSP\\FSPTest\\FSPTest\\bin\\Debug\\Proga.exe";
        ExecInfo.nShow = SW_HIDE;
        ExecInfo.lpDirectory = L"C:\\Setup\\FSP\\FSPTest\\FSPTest\\bin\\Debug";
        ExecInfo.lpParameters = NULL;
        ExecInfo.hwnd = NULL;
        ExecInfo.lpVerb = L"Open";
        if (ShellExecuteEx(&ExecInfo)){
          WaitForSingleObject(ExecInfo.hProcess, INFINITE);
          DEVICE_LIMIT = 0;
          GetExitCodeProcess(ExecInfo.hProcess, &DEVICE_LIMIT);
          CloseHandle(ExecInfo.hProcess);
        } else{
          DEVICE_LIMIT = 0;
        }
      //----вычисление DEVICE_LIMIT----



Заработало, когда явно прописал пути (выделено)
А как мне вычислить путь, где физически лежит dll (из которой все это запускается)?
На языке .Net это Application.Startup

Т.е. у меня dll лежит
"C:\\Setup\\FSP\\FSPTest\\FSPTest\\bin\\Debug\\MyDll.dll"

А вычислить надо
"C:\\Setup\\FSP\\FSPTest\\FSPTest\\bin\\Debug" //папка где она лежит
"C:\\Setup\\FSP\\FSPTest\\FSPTest\\bin\\Debug\\Proga.exe" //Proga.exe -лежит в той же папке
...
Рейтинг: 0 / 0
27.02.2017, 17:20
    #39411095
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Еще есть проблема, что при отсутствии Proga.exe в указанном месте ShellExecuteEx виснет, вместо чтоб вернуть False.
Не нравится мне все это.
...
Рейтинг: 0 / 0
27.02.2017, 17:32
    #39411104
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Вот я не могу понять, что происходит с CreateProcess при вызове из dll-ф-ции, но очевидно
что-то не то.

MSDN читать не пробовал?..
lpCommandLine
[in, out] Pointer to a null-terminated string that specifies the command line to execute.
The maximum length of this string is 32K characters.
The Unicode version of this function, CreateProcessW, will fail if this parameter is a
const string
.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.02.2017, 19:18
    #39411176
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Dimitry Sibiryakov,

Я пока застопорился как путь к папке с моей dll получить
Пробую:
Код: plaintext
1.
2.
3.
        WCHAR szDllPath[MAX_PATH_LEN] = { 0 };
        GetModuleFileName(NULL, szDllPath, MAX_PATH_LEN);
        WriteDebugString(L"   szDllPath=%s\r\n", szDllPath);


Он мне пишет:
02.27.2017@19:09:38.596: szDllPath=C:\WINDOWS\system32\fxssvc.exe

Ну, понятно, что хозяин факс-сервер, но у меня то все лежит в другом (одном) месте, мне это место надо вычислить, потому как что в CreateProcess что в ShellExecuteEx надо б полный путь пихать, тем более тек. директория надо думать System32, а не где все лежит.
...
Рейтинг: 0 / 0
27.02.2017, 19:50
    #39411202
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77,

Дмитрий77,

а внимательно почитать описание первого параметра GetModuleFileName?

авторA handle to the loaded module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
dll handle - передаётся первым параметром в DllMain
...
Рейтинг: 0 / 0
27.02.2017, 20:20
    #39411223
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Изопропил,

С этим пока нахожусь на пути к истине:
Код: plaintext
1.
2.
3.
4.
        WCHAR szDllPath[MAX_PATH] = { 0 };
        GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);
        PathRemoveFileSpec(szDllPath);
        WriteDebugString(L"   szDllPath=%s\r\n", szDllPath);


Но мне не нравится
1) Что я явно должен писать имя GetModuleHandle(L" MyDll.dll "). Она сама не знает как ее зовут?
2) PathRemoveFileSpec которая Depricated и из-за которой пришлось вставлять shlwapi.lib в Компоновщик->Ввод->Доп.зависимости и не знаю насколько это Good.

Счас буду StringCchCopy и StringCchCat делать чтоб путь к Proga.exe родить и дай бог все это методом полутыка склеится и типы строк не перепутаются.
И на всю эту фигню уйдет вечер.

Теперь понимаешь за что я люблю VB и .Net,
где у меня есть
Application.StartupPath
IO.Path.GetDirectoryName(FilePath)
IO.Path.Combine(Directory, "Proga.exe")
-это не смотря на мое предпочтение API против .Net-классов во многих случаях.
...
Рейтинг: 0 / 0
27.02.2017, 20:48
    #39411231
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Она сама не знает как ее зовут?
знает, хэндл передаётся в DllMain

с чего типам строк путаться? используй юникодные.
проблема последний бэкслэш в строке найти?

не преувеличивай трудности
...
Рейтинг: 0 / 0
27.02.2017, 20:59
    #39411234
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Изопропил,

Ну пока как-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        WCHAR szDllPath[MAX_PATH] = { 0 };
        GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);
        PathRemoveFileSpec(szDllPath);
        WriteDebugString(L"   szDllPath=%s\r\n", szDllPath);
        // szLicenseFilename is the Proga.exe file name
        WCHAR  szLicenseFilename[MAX_PATH] = { 0 };
        // Set the Proga.exe file name
        if (wcslen(szDllPath) < (sizeof(szLicenseFilename) / sizeof(szLicenseFilename[0]) - wcslen(L"\\Proga.exe"))) {
          // directory path is not too long, no need to consider changing szLicenseFilename size
          if (StringCchCopy(szLicenseFilename, MAX_PATH, szDllPath) == S_OK) {
            // StringCchCopy is OK
            StringCchCat(szLicenseFilename, MAX_PATH, L"\\Proga.exe"); //будем считать что S_OK, достали проверки
          }
        }
        WriteDebugString(L"   szLicenseFilename=%s\r\n", szLicenseFilename);


Теперь попить кофейку, пересдохнутьвздохнуть и вернуться к CreateProcess/ShellExecuteEx с позиции вымученных полных путей szDllPath/szLicenseFilename.

>не преувеличивай трудности
Угу.
...
Рейтинг: 0 / 0
27.02.2017, 21:02
    #39411236
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Изопропилхэндл передаётся в DllMain
Повтори это ещё пару раз, а то даже со второго раза, похоже, не доходит...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.02.2017, 21:17
    #39411239
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Dimitry Sibiryakov,

Игра слов видимо.
Имеется думаю ввиду, что
GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);
точно определит путь,
к загруженной dll с именем MyDll.dll,
т.е. ошибка как бы исключена и этот код правильный.

Сам запутался в попытке что-то описать словами.
...
Рейтинг: 0 / 0
27.02.2017, 21:22
    #39411240
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77,

а чем прямой путь не устраивает ?
Код: plaintext
1.
2.
3.
4.
5.
BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
  _In_ DWORD     fdwReason,
  _In_ LPVOID    lpvReserved
);


hinstDLL [in]

A handle to the DLL module. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in calls to functions that require a module handle.
...
Рейтинг: 0 / 0
27.02.2017, 21:52
    #39411249
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
ИзопропилДмитрий77,

а чем прямой путь не устраивает ?
Код: plaintext
1.
2.
3.
BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
...



Нету у меня такой.
Есть вот это (уж не знаю насколько эквивалентно):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
static HANDLE        g_hInstance;       // g_hInstance is the global handle to the module


BOOL WINAPI
DllEntryPoint(
                HINSTANCE  hInstance,
                DWORD      dwReason,
                LPVOID     pContext
             )
{
        // pDeviceInfo is a pointer to the virtual fax devices
        PDEVICE_INFO  pDeviceInfo;
        // pCurrentDeviceInfo is a pointer to the current virtual fax device
        PDEVICE_INFO  pCurrentDeviceInfo;

        if (dwReason == DLL_PROCESS_ATTACH) {
                // Set g_hInstance
                g_hInstance = hInstance;
...



Но при попытки замены
GetModuleHandle(L"MyDll.dll")
на
(HINSTANCE)g_hInstance

он мне exe-шник в System32 вычисляет

Да пофиг, я думаю мой вариант правильный.

Хотя они делают зачем-то g_hInstance = hInstance (HINSTANCE->HANDLE)
из-за чего мне приходится делать обратное (HINSTANCE)g_hInstance (HANDLE->HINSTANCE)
и вот не знаю насколько это законно и не получаю ли я тот же NULL в итоге вместо исходного HINSTANCE.
...
Рейтинг: 0 / 0
27.02.2017, 22:07
    #39411256
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Хотя они делают зачем-то
кто такие "они"?
...
Рейтинг: 0 / 0
27.02.2017, 22:24
    #39411262
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Изопропил,

"они" это MS, которые в SDK любезно предоставили рыбу этой самой dll, скелет которой я ясно дело не менял,
а просто методично подправляю под свою кухню.
...
Рейтинг: 0 / 0
27.02.2017, 22:32
    #39411264
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Есть вот это
А ты проверил, что "это" действительно вызывается? А то всё выглядит так, будто бы нет и
g_hInstance остаётся равным нулю.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.02.2017, 22:52
    #39411275
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Dimitry SibiryakovMSDN читать не пробовал?..
lpCommandLine
[in, out] Pointer to a null-terminated string that specifies the command line to execute.
The maximum length of this string is 32K characters.
The Unicode version of this function, CreateProcessW, will fail if this parameter is a
const string
.


Читаем постоянно. Но иногда там слишком много написано.
Я не знаю в чем там мистика и почему нельзя просто написать L"bla-bla-bla"
но тем не менее (с учетом вычисления полного пути к файлу и указания полного пути к директории где он лежит)
код таки завелся и работает:

Код: plaintext
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.
        WCHAR szDllPath[MAX_PATH] = { 0 };
        GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);
        PathRemoveFileSpec(szDllPath);
        WriteDebugString(L"   szDllPath=%s\r\n", szDllPath);
        // szLicenseFilename is the Proga.exe file name
        WCHAR  szLicenseFilename[MAX_PATH] = { 0 };
        // Set the Proga.exe file name
        if (wcslen(szDllPath) < (sizeof(szLicenseFilename) / sizeof(szLicenseFilename[0]) - wcslen(L"\\Proga.exe"))) {
          // directory path is not too long, no need to consider changing szLicenseFilename size
          if (StringCchCopy(szLicenseFilename, MAX_PATH, szDllPath) == S_OK) {
            // StringCchCopy is OK
            StringCchCat(szLicenseFilename, MAX_PATH, L"\\Proga.exe"); //будем считать что S_OK, достали проверки
          }
        }
        WriteDebugString(L"   szLicenseFilename=%s\r\n", szLicenseFilename);

        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
        ZeroMemory(&pi, sizeof(pi));
        WriteDebugString(L"   Proga.exe before start.\r\n");
        // Start the shelled application:
        if (CreateProcess(NULL, szLicenseFilename, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, szDllPath, &si, &pi)) {
         WriteDebugString(L"   Proga.exe started.\r\n");
          // Wait for the shelled application to finish:
          WaitForSingleObject(pi.hProcess, INFINITE);
          DEVICE_LIMIT = 0;
          GetExitCodeProcess(pi.hProcess, &DEVICE_LIMIT);
          CloseHandle(pi.hProcess);
        } else {
          WriteDebugString(L"   Proga.exe NOT started.\r\n");
          DEVICE_LIMIT = 0;
        }
        WriteDebugString(L"   DEVICE_LIMIT=%d\r\n", DEVICE_LIMIT);



Причем видимо чуть приглажу и остановлюсь на этом варианте с CreateProcess.

Можно заменить на ShellExecuteEx,
но там есть проблема.
Если Proga.exe отсутствует(файл физически удалили), по логике должен уйти по else и вернуть DEVICE_LIMIT = 0,
но почему-то этого не происходит и код виснет (служба запускается бесконечно):
(м.б. про какие-то маски/флаги не дочитал)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
        SHELLEXECUTEINFO ExecInfo;
        ZeroMemory(&ExecInfo, sizeof(ExecInfo));
        // Set up the structure.
        ExecInfo.cbSize = sizeof(ExecInfo);
        ExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ExecInfo.lpFile = szLicenseFilename;
        ExecInfo.nShow = SW_HIDE;
        ExecInfo.lpDirectory = szDllPath;
        ExecInfo.lpParameters = NULL;
        ExecInfo.hwnd = NULL;
        ExecInfo.lpVerb = L"Open";
        if (ShellExecuteEx(&ExecInfo)){
          WaitForSingleObject(ExecInfo.hProcess, INFINITE);
          DEVICE_LIMIT = 0;
          GetExitCodeProcess(ExecInfo.hProcess, &DEVICE_LIMIT);
          CloseHandle(ExecInfo.hProcess);
        } else{
          DEVICE_LIMIT = 0;
        }


В случае с CreateProcess "else" корректно отрабатывает при отсутствии файла.
...
Рейтинг: 0 / 0
27.02.2017, 23:16
    #39411285
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Dimitry SibiryakovДмитрий77Есть вот это
А ты проверил, что "это" действительно вызывается? А то всё выглядит так, будто бы нет и
g_hInstance остаётся равным нулю.

Не уверен что вызывается.
Как проверить не знаю, лог у меня включается в FaxDevVirtualDeviceCreation - первая ф-ция, вызываемая при старте Fax-службы,
там же сразу за стартом лога я вычисляю DEVICE_LIMIT для чего мне и нужен szDllPath
Но DllMain точно отсутствует.
Ну и бог с ним, раз нашел рабочий способ вычислить szDllPath.
...
Рейтинг: 0 / 0
27.02.2017, 23:29
    #39411292
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Ну и бог с ним, раз нашел рабочий способ вычислить szDllPath.
не хочешь разбираться - готовься наступить на следующие грабли
...
Рейтинг: 0 / 0
27.02.2017, 23:47
    #39411297
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77Но DllMain точно отсутствует.что мешает её написать самому?
...
Рейтинг: 0 / 0
28.02.2017, 00:00
    #39411301
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
ИзопропилДмитрий77Ну и бог с ним, раз нашел рабочий способ вычислить szDllPath.
не хочешь разбираться - готовься наступить на следующие грабли
Что за грабли меня ожидают?
Ну давай я эту DllEntryPoint закомментирую и посмотрю будет ли работать. Предполагаю что будет, хотя не уверен.
Глянь на полный код:
Код: plaintext
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.
/+---------------------------------------------------------------------------
//
//  function:   DllEntryPoint
//
//  Synopsis:   DLL entry-point function
//
//  Arguments:  [hInstance] - handle to the DLL
//                [dwReason] - specifies a flag indicating why the DLL entry-point function is being called
//
//  Returns:    TRUE on success
//
//----------------------------------------------------------------------------
BOOL WINAPI
DllEntryPoint(
                HINSTANCE  hInstance,
                DWORD      dwReason,
                LPVOID     pContext
             )
{
        // pDeviceInfo is a pointer to the virtual fax devices
        PDEVICE_INFO  pDeviceInfo;
        // pCurrentDeviceInfo is a pointer to the current virtual fax device
        PDEVICE_INFO  pCurrentDeviceInfo;

        if (dwReason == DLL_PROCESS_ATTACH) {
                // Set g_hInstance
                g_hInstance = hInstance;
                // Disable the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the DLL
                DisableThreadLibraryCalls(hInstance);
        }
        else if (dwReason == DLL_PROCESS_DETACH) {
                if (g_pDeviceInfo != NULL) {
                        // Enumerate the virtual fax devices
                        for (pCurrentDeviceInfo = g_pDeviceInfo[0]; pCurrentDeviceInfo; pCurrentDeviceInfo = pDeviceInfo) {
                                pDeviceInfo = pCurrentDeviceInfo->pNextDeviceInfo;

                                if (pCurrentDeviceInfo->ExitEvent) {
                                        // Set the event to indicate the thread to watch for an incoming fax transmission is to exit
                                        SetEvent(pCurrentDeviceInfo->ExitEvent);
                                }

                                // Delete the critical section
                                DeleteCriticalSection(&pCurrentDeviceInfo->cs);
                                // Delete the virtual fax device data
                                MemFreeMacro(pCurrentDeviceInfo);
                        }
                        g_pDeviceInfo = NULL;
                }
                // Close the log file
                CloseLogFile();
        }
        return TRUE;
}


Там как бы память очищается, и лог-файл закрывается, так что уже не уверен что оно лишнее и нигде не срабатывает.

Все одно задача как бы решена, а двигаться дальше сегодня уже неохота.
К списку "заказанных" майкрософтом функций, чье присутствие и внешний вид обязательны:
Fax Service Provider Functions
она не относится.
В SDK примере еще есть например заумные DllRegisterServer/DllUnregisterServer которые нахрен не нужны (потому как вся регистрация/unregistрация - вызов двух API-ф-ций что с комфортом можно сделать и из VB):
Код: vbnet
1.
2.
3.
4.
5.
  Public Declare Unicode Function FaxRegisterServiceProvider Lib "WinFax" Alias _
   "FaxRegisterServiceProviderW" (ByVal DeviceProvider As String, ByVal FriendlyName As String, _
   ByVal ImageName As String, ByVal TspName As String) As Boolean
  Public Declare Unicode Function FaxUnregisterServiceProvider Lib "WinFax" Alias _
   "FaxUnregisterServiceProviderW" (ByVal DeviceProvider As String) As Boolean


Но они (MS) однако нигде не говорят как потом реестр от "девайсов" чистить (после удаления "провайдера").
И в SDK примере этого также нигде нет.
Видимо предполагается либо забить на мусор, либо ручками через ф-ции реестра, что вообще говоря гимор.
...
Рейтинг: 0 / 0
28.02.2017, 00:01
    #39411302
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
egorychДмитрий77Но DllMain точно отсутствует.что мешает её написать самому?
А зачем?
...
Рейтинг: 0 / 0
28.02.2017, 00:09
    #39411304
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77egorychпропущено...
что мешает её написать самому?
А зачем?
чтоб от говнокода избавиться
...
Рейтинг: 0 / 0
28.02.2017, 01:09
    #39411311
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Ну давай я эту DllEntryPoint закомментирую и посмотрю будет ли работать. Предполагаю что будет, хотя не уверен.

Закомментировал. На работоспособность не влияет. Не знаю, зачем она там вообще.
Изопропилчтоб от говнокода избавиться
Говнокод, говнокод.
Где говнокод?
Это?
Код: plaintext
1.
GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);


MSDNRetrieves a module handle for the specified module. The module must have been loaded by the calling process .
Какой модуль должен грузить "calling process" ему четко (вместе с путем) прописано в реестре при регистрации провайдера
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fax\Device Providers\{GUID} "ImageName"
А прописываю я туда путь к dll в папке моего приложения.
Поэтому случайно загрузить что-то другое (хоть бы это другое с тем же именем в System32 лежит) он не может.
Поэтому однозначно вернет требуемый путь (где все мое "хозяйство" и лежит).
Не может тут граблей быть.

Я понимаю что ты хочешь сказать. Добавить DllMain, которая сработает при Load, а оттуда пихнуть HINSTANCE в Static, откуда взять не вычисляя через GetModuleHandle.
Ну, сделал по другому. Только где там грабли и говнокоды?
...
Рейтинг: 0 / 0
28.02.2017, 01:34
    #39411316
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с CreateProcess при запуске из-под Win службы
Дмитрий77,

говнокод - GetModuleFileName(GetModuleHandle(L"MyDll.dll"), szDllPath, MAX_PATH);
сам прекрасно понимаешь.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблемы с CreateProcess при запуске из-под Win службы / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]