想法好简单:
当第一次启动该应用的一个实例时创建一个内存影射文件
当想启动第二个或后续实例时会发现该内存影射文件已经存在,就会立刻退出程序
但现在的问题是:
每次调用 CreateFileMapping 都返回不同的m_hFileMapping值,并且GetLastError()的返回值是0,所以还是可以启动多个实例,我想问问到底我错在哪里??Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End TypeDim m_hFileMapping As LongConst c_AppName = "MyFileMap"
Const PAGE_READONLY = &H2
Const PAGE_READWRITE = &H4
Const PAGE_WRITECOPY = &H8
Const ERROR_ALREADY_EXISTS = &H183Public Declare Function GetLastError Lib "kernel32" () As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As SECURITY_ATTRIBUTES, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As LongPrivate Function CheckInstance() As Boolean
Dim sa As SECURITY_ATTRIBUTES
With sa
.nLength = 12
.bInheritHandle = 0
.lpSecurityDescriptor = 0
End With
m_hFileMapping = CreateFileMapping(&HFFFFFFFF, sa, PAGE_READWRITE, 0, 4, c_AppName)
If m_hFileMapping <> 0 And ERROR_ALREADY_EXISTS = GetLastError() Then
CloseHandle m_hFileMapping
Exit Function
End If
CheckInstance = True
End FunctionSub Main()
If Not CheckInstance Then Exit Sub
'启动应用...
End Sub
当第一次启动该应用的一个实例时创建一个内存影射文件
当想启动第二个或后续实例时会发现该内存影射文件已经存在,就会立刻退出程序
但现在的问题是:
每次调用 CreateFileMapping 都返回不同的m_hFileMapping值,并且GetLastError()的返回值是0,所以还是可以启动多个实例,我想问问到底我错在哪里??Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End TypeDim m_hFileMapping As LongConst c_AppName = "MyFileMap"
Const PAGE_READONLY = &H2
Const PAGE_READWRITE = &H4
Const PAGE_WRITECOPY = &H8
Const ERROR_ALREADY_EXISTS = &H183Public Declare Function GetLastError Lib "kernel32" () As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As SECURITY_ATTRIBUTES, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As LongPrivate Function CheckInstance() As Boolean
Dim sa As SECURITY_ATTRIBUTES
With sa
.nLength = 12
.bInheritHandle = 0
.lpSecurityDescriptor = 0
End With
m_hFileMapping = CreateFileMapping(&HFFFFFFFF, sa, PAGE_READWRITE, 0, 4, c_AppName)
If m_hFileMapping <> 0 And ERROR_ALREADY_EXISTS = GetLastError() Then
CloseHandle m_hFileMapping
Exit Function
End If
CheckInstance = True
End FunctionSub Main()
If Not CheckInstance Then Exit Sub
'启动应用...
End Sub
解决方案 »
- 高手请教!怎样自动将文件夹中新的文件上传到FTP
- 线程外如何结束_beginthread开启的线程!
- 通过WORD插件操作自定义控件若干问题讨论!欢迎加入!
- 讨论一下这个网络开发方案八。
- 数学windows编程的高手请指点指点,看看这个能不能实现
- 关于#pragma pack(push,1) 问题
- 我在线程里让视图显示,怎么晃一下就没了,怎样让它长久保持显示?
- 请问这个编译错误如何解决:msvcrtd.lib(MSVCRTD.dll) : error LNK2005: _strncpy already defined in libcmtd.lib(strncpy.obj)
- 懂VC6.0的朋友,我有一個問題急需求教,謝謝!
- CToolTipCtrl在托盘图标的应用 不用自带的tip?
- 用CStdioFile类创建文本文件后,进行n次的读和n次的写操作,不用每次都open--close行不行?只在关闭应用程序时只进行一次的open和close行
- 关于CListCtrl滚动条的问题
CloseHandle m_hFileMapping
CheckInstance = False
Exit Function
End IfGetLastError在VB里有时莫名其妙。
见http://asp.6to23.com/nowcan/tech/mutex.htm
一开始我也遇到这个问题。
HANDLE CNoCloseApp::m_hEvevtCanPopup = NULL;CNoCloseApp::CNoCloseApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
m_hEvevtCanPopup = CreateEvent(NULL,TRUE,FALSE,NULL);
Init();
WaitForSingleObject(m_hEvevtCanPopup,INFINITE);
}/////////////////////////////////////////////////////////////////////////////
// The one and only CNoCloseApp objectCNoCloseApp theApp;/////////////////////////////////////////////////////////////////////////////
// CNoCloseApp initializationBOOL CNoCloseApp::InitInstance()
{
AfxEnableControlContainer(); // Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CNoCloseDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
} // Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
DWORD CALLBACK CNoCloseApp::ListenThreadProc(void * para)
{
HANDLE hProcessToListen = (HANDLE)para;
for(;;)
{
WaitForSingleObject(hProcessToListen,INFINITE);
hProcessToListen = CreateBuddy();
SetEvent(m_hEvevtCanPopup);
}
return 0;
}BOOL CNoCloseApp::Init()
{
HANDLE hProcessToListen;
HANDLE hThreadListen;
DWORD ProcessID;
LPTSTR lpCmdLine = GetCommandLine(); if( sscanf(lpCmdLine,"%X",&ProcessID) != 1 )//没有参数,此进程是首先执行的
{
hProcessToListen = CreateBuddy();
if( NULL == hProcessToListen )
return FALSE;
SetEvent(m_hEvevtCanPopup);
}
else//有参数,作为后台运行
{
hProcessToListen = OpenProcess(PROCESS_ALL_ACCESS,TRUE,ProcessID);
if( NULL == hProcessToListen )//句并不对
return FALSE;
CString s;
s.Format("HProcess:0x%X",hProcessToListen);
} hThreadListen = ::CreateThread(NULL,NULL,ListenThreadProc,
(LPVOID)hProcessToListen,
CREATE_SUSPENDED,&ProcessID);
::SetThreadPriority(hThreadListen,THREAD_PRIORITY_TIME_CRITICAL);
::ResumeThread(hThreadListen); return TRUE;
}HANDLE CNoCloseApp::CreateBuddy()
{
STARTUPINFO StartInfo;
PROCESS_INFORMATION pinfo;
char filename[MAX_PATH];
char para[16]; GetModuleFileName(NULL,filename,MAX_PATH);
sprintf(para,"%X",GetCurrentProcessId());
memset(&StartInfo,0,sizeof(STARTUPINFO));
StartInfo.cb = sizeof(STARTUPINFO); if( ! CreateProcess(
filename,
para,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&StartInfo,
&pinfo) )//创建进程失败 return NULL; return pinfo.hProcess;
}
void CNoCloseDlg::OnClose()
{
MessageBox("I said NO USE",":)",MB_OK|MB_ICONSTOP);
}BOOL CNoCloseDlg::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN)
return TRUE;
return CDialog::PreTranslateMessage(pMsg);
}
{
HANDLE hMap=CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,PAGE_READWRITE, 0, 128,"MutexNc");
if(hMap==NULL)
{
AfxMessageBox("创建用于互斥运行的内存映射文件对象失败!",MB_OK|MB_ICONSTOP);
return FALSE;
}
else if(GetLastError()==ERROR_ALREADY_EXISTS)
{
HWND hWndPrevious=::FindWindow(NULL, "密码校验");
if (hWndPrevious!=NULL)
{
// 主窗口已最小化,则恢复其大小
if (::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious,SW_RESTORE);
// 将主窗激活
ShowWindow(hWndPrevious,SW_SHOW);
::SetForegroundWindow(hWndPrevious);
// 将主窗的对话框激活
::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));
return false;
// 退出本实例
}
}
else
{
LPVOID lpMem = MapViewOfFile(hMap, FILE_MAP_WRITE, 0,0,0);
strcpy((char*)lpMem, "程序正在运行!");
UnmapViewOfFile(lpMem);
}
return true;
}