Как перенаправить выполнение программы на вызов функции в уже запущенном экземпляре той же программы? - PullRequest
0 голосов
/ 17 апреля 2020

Я написал программное обеспечение для управления данными / анализа для работы. Программное обеспечение сохраняет данные в виде текстовых файлов базы данных. Теперь я реализовал сопоставление типов файлов и обработку двойного щелчка, чтобы запустить программу и открыть файл базы данных. Чтобы пользователи случайно не испортили свои файлы, я установил мьютекс, чтобы разрешить только один экземпляр программы. Теперь я хотел бы перенаправить выполнение второго экземпляра в функцию open () уже запущенного экземпляра, а не просто блокировать его. Итак, у меня есть два вопроса:

1) Существует ли простой / очевидный способ перенаправить выполнение второго экземпляра на вызов функции первого экземпляра?

I попытался объединить мьютекс с именованным каналом в следующем примере: создать канал имен c windows

Сервер:

private: System::Void createNamedPipe() {
        char buffer[1024];
        DWORD dwRead;
        std::string temp{};

        hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,   // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
            1,
            1024 * 16,
            1024 * 16,
            NMPWAIT_USE_DEFAULT_WAIT,
            NULL);
        while (hPipe != INVALID_HANDLE_VALUE)
        {
            if (ConnectNamedPipe(hPipe, NULL) != FALSE)   // wait for someone to connect to the pipe
            {
                while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE) {
                    /* add terminating zero */
                    buffer[dwRead] = '\0';

                    /* do something with data in buffer */

                    temp = buffer;
                }
                openOrImport(temp); //executes the open routine in my form
            }
            DisconnectNamedPipe(hPipe);
        }
    }

Клиент:

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) {

//set a mutex to prevent multiple instances of the program
HANDLE hMutexCurrentApp = CreateMutex((LPSECURITY_ATTRIBUTES) NULL, (BOOL) TRUE, (LPCTSTR) "CellDB");
DWORD dwLastError = GetLastError();

if (dwLastError == ERROR_ALREADY_EXISTS)
{
    // Process already running.
    CloseHandle(hMutexCurrentApp);
    hMutexCurrentApp = NULL;

    //create named pipe client to trigger a function in the already running instance
    HANDLE hPipe;
    DWORD dwWritten;

    hPipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
    if (hPipe != INVALID_HANDLE_VALUE)
    {
        std::string path{};
        path = lpCmdLine;
        path = path.substr(1, path.length() - 2);
        WriteFile(hPipe, path.c_str(), path.length(),   // = length of string + terminating '\0' !!!
            &dwWritten, NULL);

        CloseHandle(hPipe);
    }

    return 1;
}

Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
CellDB::MyForm form(lpCmdLine);
Application::Run(%form);

//releases mutex
CloseHandle(hMutexCurrentApp);
hMutexCurrentApp = NULL;

return 0;}

Пока он работает (также многократно), выполнение openOrImport () является чрезвычайно медленным, хотя он использует только несколько% ЦП. Итак, второй вопрос:

2) Почему комбинация мьютекса и именованного канала такая медленная?

РЕДАКТИРОВАТЬ: Это был конфликт потоков, вызванный запуском канала в фоновом режиме. Перемещение функции open () в основной поток решило проблему.

Извините, если я что-то упустил очевидное, у меня никогда не было формального обучения программированию: -)

...