起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 387|回复: 19

[结贴]急需解决,关于在X3中引入外部控件,代码中含有ShareMem库导致客户端退出CPU占用1

[复制链接]
发表于 2009-9-9 16:58:04 | 显示全部楼层 |阅读模式
X3平台:2827版本

我需要在平台中调用winrar.exe对文件夹进行压缩,程序使用CreateProcess对压缩完成情况进行监控,由于CreateProcess中含有指针类型,平台不

支持,所以我另外用Delphi6+SP2写了一个小DLL封装这个函数,这个封装的DLL如果不uses ShareMem,那么在XP系统下可以正常创建进程,在vista下

会创建进程失败,如果uses ShareMem,那么封装出来的DLL还必须要带上Delphi的borlndmm.dll才能运行,在XP系统下能正常创建进程,但是在退出

系统的时候会报内存X00000000的错误,在vista系统上也能正常创建压缩进程,但是退出的时候客户端不释放,占用CPU100%(系统是双核,启动一

个客户端退出占50%,启动两个客户端退出就是每个50%)

部分代码应用情况的说明:

情况一:
使用ShareMem
uses ShareMem
使用FillChar初始化
FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP和vista都能创建进程,但是在XP退出会报错,在vista退出客户端不释放

情况二:
不使用ShareMem
//uses ShareMem
使用FillChar初始化
FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP和vista都不能创建进程,但是退出客户端都正常

情况三
不使用ShareMem
//uses ShareMem
不使用FillChar初始化
//FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP能正常创建进程,在vista创建进程失败,退出客户端都正常

DLL应用代码(生成Dll命名空间是Rarp):
procedure TCT_TEST.ButtonClick(Sender: TObject);
var
    StartupInfo : Borland.Delphi.Windows.TStartupInfo;
    ProcessInfo : Borland.Delphi.Windows.TProcessInformation;
    lCmdLine : string;
    hProcess,hThread : Cardinal;
    lb : boolean;
begin
     lCmdLine := 'D:\temp\winrar.exe a -r D:\temp\test.rar D:\temp\Test';
     lb := Rarp.RarEX.RarProcess(lCmdLine,hProcess,hThread);

     if lb then
     begin
         Borland.Delphi.Windows.WaitForSingleObject(hProcess, Borland.Delphi.Windows.INFINITE);

         Borland.Delphi.Windows.CloseHandle(hProcess);
         Borland.Delphi.Windows.CloseHandle(hThread);
     end;
end;

下面附各种情况下编译的DLL和一份pas文件以及winrar.exe文件:

rarpex.rar

27.58 KB, 下载次数: 103

回复

使用道具 举报

 楼主| 发表于 2009-9-9 17:00:33 | 显示全部楼层
刚才winrar.exe没有打包进去,重新发一个

rarpex.rar

152.38 KB, 下载次数: 109

回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-10 08:28:42 | 显示全部楼层
有人能帮忙指导一下么?
回复 支持 反对

使用道具 举报

发表于 2009-9-10 08:47:34 | 显示全部楼层
你可以不封装dll,直接当作一个unit导入到平台。这样就少了一步比较麻烦的dll传递参数的问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-10 09:28:54 | 显示全部楼层
当作unit这个怎么导?
回复 支持 反对

使用道具 举报

发表于 2009-9-10 09:44:31 | 显示全部楼层
用导入第三方控件方法导入。
http://bbs.justep.com/forum.php?mod=viewthread&tid=20086
你的pas文件可以当作4楼的tlb.pas文件用。下面步骤都一样了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-10 10:13:52 | 显示全部楼层
我就是已经做成第三方导入了啊,我知道怎么导入到X3,问题是是导入的DLL在不同的操作系统上出现不同的错误,用不了啊,我提供的包里就是已经生成了的DLL和BPL文件,另外还提供了生成前的PAS控制文件
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-10 10:16:24 | 显示全部楼层
部分代码应用情况的说明:

情况一:
使用ShareMem
uses ShareMem
使用FillChar初始化
FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP和vista都能创建进程,但是在XP退出会报错,在vista退出客户端不释放

情况二:
不使用ShareMem
//uses ShareMem
使用FillChar初始化
FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP和vista都不能创建进程,但是退出客户端都正常

情况三
不使用ShareMem
//uses ShareMem
不使用FillChar初始化
//FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
在XP能正常创建进程,在vista创建进程失败,退出客户端都正常

上面那部分是对控制文件PAS的应用情况说明,三种不同的代码导致生成的DLL和BPL导入X3后在不同系统上会有不同的错误出现
回复 支持 反对

使用道具 举报

发表于 2009-9-10 10:23:34 | 显示全部楼层
你用delphi调用dll试试,如果delphi也抱错,先解决错误。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-14 10:01:36 | 显示全部楼层
这些都是用X3Importer中的DelphiImporter.exe生成的DLL和BPL,在delphi的测试工程里引用运行时出现初始化失败的错误,无法使用,但是同样的代码使用delphi直接生成DLL文件使用没有问题
DLL的代码:
library RarpEx;

uses
  ShareMem,
  SysUtils,
  Classes,
  Windows, Dialogs;

{$R *.res}

function RarProcess(ACmdLine :string;var hProcess,hThread:Cardinal):Boolean;stdcall;
var
    StartupInfo : TStartupInfo;
    ProcessInfo : TProcessInformation;
begin
    FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
    StartupInfo.cb:=SizeOf(StartupInfo);
    StartupInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_HIDE;

    if not CreateProcess(nil,PChar(ACmdLine),nil,nil,False,
       CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
       nil,nil, StartupInfo, ProcessInfo) then
    begin
        Result := false;
        exit;
    end;

    hProcess := ProcessInfo.hProcess;
    hThread  := ProcessInfo.hThread;
    Result := true;
end;

exports
  RarProcess;

begin
end.

测试工程的代码:
unit testForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function RarProcess(ACmdLine : String;var hProcess,hThread: Cardinal):Boolean;stdcall;external 'RarpEx.dll'

procedure TForm1.Button1Click(Sender: TObject);
var
    hProcess,hThread : Cardinal;
    lb : boolean;
    lCmdLine : string;
begin
   
    lCmdLine := Edit2.Text;
    //lCmdLine := 'F:\temp\winrar.exe a -r F:\temp\test.rar F:\temp\Test';
    lb := RarProcess(lCmdLine,hProcess,hThread);

     if lb then
     begin
         WaitForSingleObject(hProcess, INFINITE);

         CloseHandle(hProcess);
         CloseHandle(hThread);
     end;

end;

end.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-16 05:29 , Processed in 0.042262 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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