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