我最近在做一个程序,在电脑上运行要能记录使用情况,现在的关键在怎么来判断是不是第一次运行这个程序.我目前是通过在C盘和注册表里都写入记录来判断.可是这有一个缺陷,就是很多杀毒软件都能检测到往C盘或注册表里写入的东西,这样如果用户把写进去的东西删了,就会又以为是第一次运行了..
还有一个问题是,我做了个DLL,要通过这个DLL关闭主程序,我现在是先让主程序在调用DLL时告诉DLL主程序的句柄,然后用PostMessage(句柄,WM_CLOSE,0,0)来关闭主程序.可是我们头说调用时还要告诉DLL句柄太麻烦了,大家能不能帮我想想没有没什么其他方法不用句柄来关闭或是让DLL自动找到主程序的句柄呢??

解决方案 »

  1.   

    把dll注入其它进程.再关闭主程序
    判断是不是第一次运行你可以在非C盘写一个标识文件吧
    最好是写注册表
      

  2.   

    1.CreateMutex创建一个互斥变量!
    2.最好是自己自定义一个消息,要关闭时发这个自定义的消息给主程序,
    主程序接受后就会进行一些处理,例如一些连接的关闭啊,资源的释放(例如DLL),
    最后才去调用Application.Terminate; 这样就合理了! 
      

  3.   

    to brightyang:
    把dll注入其它进程.再关闭主程序
    判断是不是第一次运行你可以在非C盘写一个标识文件吧
    最好是写注册表DLL注入其他进程,之后可是我怎么知道我要关的是哪个程序呢??我是想让主程序调用DLL后,几小时后自动关闭的.(ps:且不一定只有一个主程序使用这个DLL的.)
    在非C盘写的话,如果碰到有些电脑只有C盘怎么办?因为这个程序是拿到客户那用,不能保证客户一定有其他盘或是在使用过程中格式化其他盘的.
      

  4.   

    to chenzhuo(睡到自然醒) :
    1.CreateMutex创建一个互斥变量!
    2.最好是自己自定义一个消息,要关闭时发这个自定义的消息给主程序,
    主程序接受后就会进行一些处理,例如一些连接的关闭啊,资源的释放(例如DLL),
    最后才去调用Application.Terminate; 这样就合理了! 1、互斥变量怎么用?能稍微说详细一点吗?我没接触过这东西。^^
    2、问题我要把功能都做到DLL里,这样其他程序想用时只能一句话就能执行定时自动关闭的功能。
    再帮我想想吧。。
      

  5.   

    program Project1;uses
      Forms,Windows,Dialogs,
      Unit1 in 'Unit1.pas' {Form1};{$R *.RES}begin
      CreateMutex(nil,False,'{EC5F94F0-5BD7-4FDF-AFB2-855ED3911C98}');
      if GetLastError = ERROR_ALREADY_EXISTS then
      begin
        ShowMessage('程序已经在运行');
        Exit;
      end;  Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.2.不知道你想做什么?
      

  6.   

    to chenzhuo(睡到自然醒):
    1、呵呵,你误解我的意思了。你这个程序是用来实现只能运行一个客户端的吧。我想做的是,每次打开客户端时能判断该程序是不是在这台电脑上初次运行。当然,我可以在电脑上写文件把记录写进去,可是有被删的危险哇。所以是在想怎么在电脑上做记录,做得隐蔽点比较好。
    不过你的程序挺有意思的,我想以后我会用得早。谢谢了2、在DLL里我是想让它关闭让程序。就比如DLL中有一个函数DestoryHost()。主程序一调用这个DestoryHost就会在一小时后自动关闭。前提是在调用DestoryHost时不能传递任何参数,一切都要靠DLL中DestoryHost函数内部代码现实。
      

  7.   

    说说我的一些想法:
      第一个问题:
      1)向系统文件夹下写文件,属性中加上只读/隐藏/系统,这样一般人不会发现。程序运行时以独占方式打开,拒绝修改/删除。
      2)向程序自身写数据,将程序运行的次数加密后写到自己的尾部。不过这个比较麻烦。每次运行时读取这个值。  第二个问题:
      不知道你是多线程还是单线程的。
       1) 如果是单线程,可以先GetCurrentProcessId,然后TerminateProcess。哈哈,还是别这样做。馊主意。
       2) 要不就枚举所有的窗体,然后调用GetWindowThreadProcessId,看是否等于GetCurrentProcessId,等于,发送消息关闭。好麻烦,还不如直接将句柄传递过来。
       3) 要不就自定义消息,然后,PostThreadMessage(GetCurrentProcessId, WM_MYMessage,..),处理这个自定义消息,关闭主窗体。这个没试过,不知道可不可以。 ^_^  呵呵,发现我的馊主意挺多的!嘿嘿....
      

  8.   

    最近要忙毕业设计的事,手头的工作要先放放了,所以这个帖子先结了,谢谢大家的帮忙.
    第一个问题还是没找到好的办法,第二人问题我目前通过遍历进程,再遍历DLL来解决了.^&^