找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 6991|回复: 4

[其它源码] 禁止程序重复运行

[复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2011-7-8 07:42:31 | 显示全部楼层 |阅读模式
创建一个信号灯就可以了

Private Declare Function ReleaseSemaphore Lib "kernel32" (ByVal hSemaphore As Long, ByVal lReleaseCount As Long, lpPreviousCount As Long) As Long

Private Declare Function CreateSemaphore Lib "kernel32" Alias "CreateSemaphoreA" (lpSemaphoreAttributes As SECURITY_ATTRIBUTES, ByVal lInitialCount As Long, ByVal lMaximumCount As Long, ByVal lpName As String) As Long

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Dim Semaphore As String, Sema As Long, Security As SECURITY_ATTRIBUTES
Dim PrevSemaphore As Long, Turn As Long
Private Sub Form_Load()
   Security.bInheritHandle = True
   '默认的安全值
   Security.lpSecurityDescriptor = 0
   Security.nLength = Len(Security)
   Semaphore = "这里自己随便起个名"
   '创建或打开一个Semaphore记数信号,设资源空闲使用量为1
   Sema = CreateSemaphore(Security, 1, 1, Semaphore)
   '申请一个权限,并立即返回
   Turn = WaitForSingleObject(Sema, 0)
   '如果不是正常返回,则表示没有申请到资源的使用权限
   If Turn <> 0 Then
      MsgBox "管理系统已经运行!", vbOKOnly + vbCritical, "提示"
      End
   End If
End Sub
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

 楼主| 发表于 2011-7-8 07:43:59 | 显示全部楼层
vb有句经典的话,if app.previnstance=true then end 这样可以防止重复运行,但是有个缺点就是
如果别的目录有个相同的程序这句话就会没用了。
我这个代码是创建事件同步对象达到防止重复运行的
code:
Option Explicit
Private Declare Function OpenEvent Lib "kernel32" Alias "OpenEventA" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal lpName As String) As Long
Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long

Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
End Type

Private Sub Form_Load()
Dim Attrib As SECURITY_ATTRIBUTES
    If OpenEvent(2031619, False, "myappname") <> 0 Then End ' "myappname"可以是任何文本,但是最好要长一点以保证和系统中已有其他事件对象的名称不相冲突。
    Call CreateEvent(Attrib, False, False, "myappname")
End Sub
好不好使大家自己试试吧……
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

 楼主| 发表于 2011-7-8 07:44:12 | 显示全部楼层
使用互斥也可以:


转帖:

只容许运行“一次”程序实例(利用互斥体)

选择启动对象为sub main()

module:

Public Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" _ (lpMutexAttributes As SECURITY_ATTRIBUTES, ByVal bInitialOwner As Long, ByVal lpName _
As String) As Long
Public Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
End Type
Public Const ERROR_ALREADY_EXISTS = 183&
Private Sub Main()
    Dim sa As SECURITY_ATTRIBUTES
    sa.bInheritHandle = 1
    sa.lpSecurityDescriptor = 0
    sa.nLength = Len(sa)
    Debug.Print CreateMutex(sa, 1, App.Title)  '这一行可千万不能删除啊
    Debug.Print Err.LastDllError
    If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
        MsgBox "More than one instance"
    Else
    Form1.Show
    End If
End Sub

只能启动一次,再启动都报错 :-(
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

 楼主| 发表于 2011-7-8 07:45:29 | 显示全部楼层
无论程序在何地,只能运行一个应用程序示例
模块中:

'程序实现功能:自动激活前一个实例


Public Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As SECURITY_ATTRIBUTES, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function FlashWindowEx Lib "user32.dll" (ByRef pfwi As FLASHWINFO) As Long


Private Const FLASHW_STOP = 0 '停止闪烁,系统恢复窗体到她原始的状态.
Private Const FLASHW_CAPTION = &H1 '闪烁窗体的标题
Private Const FLASHW_TRAY = &H2 '闪烁任务栏
Private Const FLASHW_ALL = (FLASHW_CAPTION Or FLASHW_TRAY) '标题栏&窗体标题一起闪烁
Private Const FLASHW_TIMER = &H4 '连续的闪烁,直到设置了FLASHW_STOP标志

Private Const ERROR_ALREADY_EXISTS = 183&
Private Const SW_RESTORE = 9
Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
End Type

Private Type FLASHWINFO
    cbSize As Long   '结构大小
    hwnd As Long
    dwFlags As Long
    uCount As Long   '闪烁的次数
    dwTimeout As Long  '闪烁的时间
End Type


Public Mutex As Long

Private Sub Main()
    Dim sa As SECURITY_ATTRIBUTES
    Dim hwnd As Long
    Dim FlashInfo As FLASHWINFO

    sa.bInheritHandle = 1
    sa.lpSecurityDescriptor = 0
    sa.nLength = Len(sa)
    Mutex = CreateMutex(sa, 1, App.Title) '试着创建一个新的互斥体
    If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then        '互斥体已经存在,表明已打开一个实例
        hwnd = GetSetting("AppName", "Section", "Key", 0)    '找到我们保存的前一个实例的句柄,这样避免了使用FindWindow函数等对变标题程序的无奈
        ShowWindow hwnd, SW_RESTORE         '显示窗口
        SetForegroundWindow hwnd            '激活窗体
        
        FlashInfo.cbSize = Len(FlashInfo)
        FlashInfo.dwFlags = FLASHW_ALL Or FLASHW_TIMER
        FlashInfo.dwTimeout = 0       '以毫秒为单位指定窗体闪烁的速率,如果为0,则使用默认的光标闪烁速率.
        FlashInfo.hwnd = hwnd
        FlashInfo.uCount = 3        '指定闪烁的次数.
        FlashWindowEx FlashInfo     '闪烁效果
    Else
        FrmMain.Show                        '显示主窗体
    End If
End Sub

窗体中:

Private Sub Form_Load()
    SaveSetting "AppName", "Section", "Key", Me.hwnd   '临时保存我们的窗体句柄
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ReleaseMutex Mutex                                  '释放互斥体,没有这两句,你在VB环境下这可以运行一次,再次按F5的时候你会发现自动退出
    CloseHandle Mutex
    DeleteSetting "AppName", "Section", "Key"           '清除我们在注册表种存放的数据,绿色效果。
End Sub


【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

858

主题

2638

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36138
发表于 2011-7-8 23:02:50 | 显示全部楼层
sub form_load()
    if dir("c:\xxx.tmp",vbDirectory)<>"" then
        msgbox "程序已经运行"
        end
    else
        mkdir "c:\xxx.tmp"
    end if

sub form_unload()
    rmdir "c:\xxx.tmp"
end sub
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表