写了两个COM 写了一个批处理reg.batregserv32  C:\MyCom\COMReport.dll
regserv32  C:\MyCom\COMADO.dll运行后,执行到第一个后就不动了.如果单独执行第二的话就是好的.
如果将两个都用 运行来执行的话,也都是好的.可以正常使用.不知道是什么原因下面是正常的那个COMlibrary ProADOConnPool;uses
//  ShareMem,
  Forms,
  Windows,
  ComServ,
  ADOConnPool in 'ADOConnPool.pas',
  UADOConnPool in 'UADOConnPool.pas',
  ProADOConnPool_TLB in 'ProADOConnPool_TLB.pas';exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;{$R *.TLB}{$R *.RES}procedure MyDLLHandler(Reason: integer);
begin
  case Reason of
    DLL_PROCESS_DETACH:
      begin
      //  Application:=FDllApp;
       // Application.MessageBox('Free','ok',0);
      //  ShowMessage('整个DLL的善後程序');
      end;
    DLL_Process_Attach:
      begin
       // ShowMessage('整个DLL的初始化代码');
      end;    DLL_Thread_Attach:
      begin
       // ShowMessage('当主叫端开始一个Thread时');
      end;
    DLL_Thread_Detach:
      begin
       // ShowMessage('当主叫端终止一个Thread时');
      end;
  end;end;begin
  DLLProc := @MyDLLHandler;
  MyDLLHandler(DLL_Process_Attach);
end.
下面是那个不正常的COM,因为里面有窗体,所以给传递了APPLICATION
注册后就是不通出控制台窗口,系统的任务管理器中也有一个regsvr32.exe 要怎么样写才能让控制台注册后正常退出??不退出的原因是什么??library ProSummaryCom;uses
  //ShareMem,
  ComServ,
  Windows,
  Forms,
  ReportSummary in 'ReportSummary.pas',
  UReportSummary in 'UReportSummary.pas',
  其它的一些窗体;exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;
{$R *.TLB}{$R *.RES}begin
  DLLProc := @DLL_MyDLLProc; // 实现在 ReportSummary单元
  DLL_MyDLLProc(DLL_Process_Attach);
end.
unit ReportSummary;
.....  procedure DLL_MyDLLProc(Reason: Integer);stdcall;
  procedure DLL_SetApplication(App:Integer);stdcall;
  function DLL_GetDLLApplication:TApplication;stdcall;implementationvar
  //DLL 原来自己的Applicaton
  FDllApp:TApplication;procedure DLL_SetApplication(App:Integer);
begin
//给Dll设置Application 和主程序相同
  if (App<>Integer(Application)) then
  begin
    FDllApp:=Application;
    Application:=TApplication(App);
  end;
end;function DLL_GetDLLApplication:TApplication;
begin
//得到DLL原来的 Application
  Result:=FDllApp;
end;procedure DLL_MyDLLProc(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_DETACH:
      begin
        //恢复Dll
        if Assigned(FDllApp) then
          Application:=FDllApp;
        Windows.Beep(4000,100);
      end;
    DLL_Process_Attach:
      begin
        FDllApp:=nil;
        Windows.Beep(1000,100);
      end;    DLL_Thread_Attach:
      begin
       // ShowMessage('当主叫端开始一个Thread时');
      end;
    DLL_Thread_Detach:
      begin
       // ShowMessage('当主叫端终止一个Thread时');
      end;
  end;end;

解决方案 »

  1.   

    试一下
    [code=BatchFile]start regserv32  C:\MyCom\COMReport.dll 
    start regserv32  C:\MyCom\COMADO.dll [/code]
      

  2.   

    我曾经都试过,是你的dll代码有问题,COMReport.dll是否使用过GDI+?
      

  3.   

    僵哥 的方法到是让CMD控制台关闭了,但任务管理器中运行的regsvr32.exe 还在.是用到了GDI+ ,报表汇总中它绘制了曲线.是GDI+的问题吗?我测试一下.要是的话如何解决呢??
      

  4.   

    在楼上各位的提示下,问题解决了.下面是我找到的比较详细的关于这个问题的资料GdiplusStartup(token, input, output)The GdiplusStartup function initializes GDI+. Call GdiplusStartup before making any other GDI+ calls, and call GdiplusShutdown when you have finished using GDI+.GdiplusStartup函数用来初始化GDI+.在任何GDI+调用前要先用GdiplusStartup初始化;当你不再使用GDI+时记得要调用GdiplusShutdown.Status GdiplusStartup(  ULONG_PTR* token,  const GdiplusStartupInput* input,  GdiplusStartupOutput* output);Parameters参数token
        [out] Pointer to a ULONG_PTR that receives a token. Pass the token to GdiplusShutdown when you have finished using GDI+. 
        指向用来接收token(记号)的ULONG_PTR.当结束使用GDI+时将这个token(记号)传入GdiplusShutdown.  
    input
        [in] Pointer to a GdiplusStartupInput structure that contains the GDI+ version, a pointer to a debug callback function, a Boolean value that specifies whether to suppress the background thread, and a Boolean value that specifies whether to suppress external image codecs. 
        指向包含GDI+版本,一个调试回调函数指针,一个指示是否禁用后台线程布尔值和一个指示是否禁用外部图像编解码器的布尔值的GdiplusStartupInput结构, 
    output
        [out] Pointer to a GdiplusStartupOutput structure that receives a pointer to a notification hook function and a pointer to a notification unhook function. If the SuppressBackgroundThread data member of the input parameter is FALSE, then this parameter can be NULL. 
        指向一个接收通知挂钩(钩子)函数的指针和一个通知解除挂钩(钩子)函数的指针.如果输入参数中禁用后台线程数据成员(即SuppressBackgroundThread)值为FALSE,这个参数(output)可以设置为NULL.Return Values返回值If the function succeeds, it returns Ok, which is an element of the Status enumeration.如果函数成功,返回OK(枚举Status中的一项).If the function fails, it returns one of the other elements of the Status enumeration.如果函数执行失败将返回枚举Status中的任一其它项.
    Res注:You must call GdiplusStartup before you create any GDI+ objects, and you must delete all of your GDI+ objects (or have them go out of scope) before you call GdiplusShutdown.在你创建任何GDI+对象前必须首先调用GdiplusStartup,而且在你调用GdiplusShutdown之前删除完(或..理解不了)所有你所创建所有GDI+对象.You can call GdiplusStartup on one thread and call GdiplusShutdown on another thread as long as you delete all of your GDI+ objects (or have them go out of scope) before you call GdiplusShutdown.你可以在一个线程调用GdiplusStartup,并用可以在另一个线程调用GdiplusShutdown,只要你在调用GdiplusShutdown前删除了所有你创建的GDI+对象(或......).Do not call GdiplusStartup or GdiplusShutdown in DllMain or in any function that is called by DllMain. If you want to create a DLL that uses GDI+, you should use one of the following techniques to initialize GDI+:切勿在DLLMAIN或任何由DLLMAIN调用的函数中调用GdiplusStartup或GdiplusShutdown( 真TMD难理解,一层又一层-_-!!).如果你想创建一个使用GDI+的DLL(动态链接库),你应该使用其下的任一方法来初始化GDI+.    * Require your clients to call GdiplusStartup before they call the functions in your DLL and to call GdiplusShutdown when they have finished using your DLL.
        * 命令你的客户机程序(执行程序)在调用DLL中的函数前先调用GdiplusStartup,在结束使用DLL时调用GdiplusShutDown.
        * Export your own startup function that calls GdiplusStartup and your own shutdown function that calls GdiplusShutdown. Require your clients to call your startup function before they call other functions in your DLL and to call your shutdown function when they have finished using your DLL.
        * 输出自定义的调用GdiplusStartup的启动函数和调用GdiplusShutdown的关闭函数.命令你的客户机程序在调用DLL中的函数前调用自定义启动函数,在结束使用DLL时调用自定义的关闭函数. 
        * Call GdiplusStartup and GdiplusShutdown in each of your functions that make GDI+ calls.
        * 在每个进行GDI+调用的函数中调用GdiplusStartup和GdiplusShutdown. Example Code [C++]示例代码[C++]For an example of calling GdiplusStartup and GdiplusShutdown in a Windows application, see Getting Started.请在Getting Started中查看关于在窗口程序中调用GdiplusStartup和GdiplusShutdown的示例.(很可惜我没能找到这个示例,相关示例请查看"在VC6中使用GDI+".The following console application uses a GDI+ Image object to retrieve the width and height of a JPEG image. The code calls GdiplusStartup before creating the Image object and calls GdiplusShutdown before terminating. Note that the Image object is deleted before the call to GdiplusShutdown.下列控制台程序使用GDI+的Image对象接收JPEG图像的宽和高.代码在创建Image对象前调用GdiplusStartup,在终结前调用GdiplusShutdown.注意Image对象在调用GdiplusShutdown前被删除.In the following code, the variable gdiplusStartupInput is initialized by the default constructor of the GdiplusStartupInput structure. The default constructor sets the data members of the structure to the following values:下列代码中,变量gdiplusStartupInput由GdiplusStartupInput结构的默认构造函数(?)初始化.默认构造函数将结构中的数据成员值进行如下设置:    * GdiplusVersion = 1
        * DebugEventCallback = NULL
        * SuppressBackgroundThread = FALSE
        * SuppressExternalCodecs = FALSE #include <windows.h>#include <gdiplus.h>#include <stdio.h>using namespace Gdiplus;INT main(){   Gdip