从delphi执行Win Forms可执行文件.任务启动后不工作

本文关键字:任务启动 工作 可执行文件 Forms delphi 执行 Win | 更新日期: 2023-09-27 18:05:27

我正在尝试从Codegear Delphi 2007中编写的代码启动可执行文件。我已经成功地做到了这一点,但是一旦可执行程序(这是一个winforms应用程序)启动,它就不会启动它所编程的Task

下面是我用来从Delphi启动进程的代码:
procedure TfrmMain.OpenDatabase1Click(Sender: TObject);
var filename: string;
var parameters: string;
var
    sei: TShellExecuteInfo;
    ExitCode: DWORD;
begin
  if (OpenDatabaseDialog.Execute)then begin
    //Connect to mysql, check for new data and insert data into sdb file before opening.
    filename := 'C:'mysqlhelper'SSOAP Mysql Helper.exe';
    parameters := '"' + OpenDatabaseDialog.FileName + '"';
    ZeroMemory(@sei, SizeOf(sei));
    sei.cbSize := SizeOf(TShellExecuteInfo);
    sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI or SEE_MASK_NOCLOSEPROCESS;
    sei.lpVerb := PChar('runas');
    sei.lpFile := PChar(filename); // PAnsiChar;
    if parameters <> '' then
      sei.lpParameters := PChar(parameters); // PAnsiChar;
    sei.nShow := SW_SHOWNORMAL; //Integer;
    if ShellExecuteEx(@sei) then begin
      repeat
        Application.ProcessMessages;
        GetExitCodeProcess(sei.hProcess, ExitCode) ;
      until (ExitCode <> STILL_ACTIVE) or  Application.Terminated;
    end;
    OpenDatabase(OpenDatabaseDialog.Filename);
  end;
end;

下面是c#的代码,作为一个独立的代码运行得很好:

public Form1()
{
    InitializeComponent();
    //get command line arguments (should be ssoap database filename
    string[] args = Environment.GetCommandLineArgs();
    //open connections
    OpenMySQLConnection();
    OpenAccessConnection(args[1]);
    //init the lists for FM's and RG's
    flowMeters = new List<FlowMeter>();
    rainGauges = new List<RainGauge>();
    Task t = new Task(new Action(DoWork));
    t.Start();
}

我已经调试到我感觉Task没有启动的程度。我已经把MessageBox.Show()点放在了整个位置,它构成了t.Start();部分。

澄清一下,我的问题是,为什么我可以启动可执行文件,给它它所期望的参数,而它只是不启动Task ?

从delphi执行Win Forms可执行文件.任务启动后不工作

从Delphi程序启动进程与作为独立应用程序启动进程之间最明显的区别是工作目录的状态。

  1. 在Delphi代码中,您不指定工作目录。因此,新进程继承了其父进程的工作目录,即Delphi程序。你没有说Delphi程序的工作目录是什么,所以我们不知道。
  2. 在Delphi程序之外启动c#程序时,工作目录将由您启动c#程序的方式确定。你没有说明如何启动c#程序,所以我们也无法知道工作目录是什么。

我建议你在c#程序中添加一些诊断代码来显示工作目录是什么。如果运行程序的两种方式不同,请在调用ShellExecuteEx时指定工作目录。

如果这证明工作目录是问题所在,那么您需要弄清楚为什么程序依赖于工作目录。这是故意的吗?如果是这样,那么您需要注意指定它。更有可能的是,程序不应该依赖于工作目录。

另一个可能的原因是传递给程序的实参。再次使用诊断输出来检查程序在两种启动模式下是否确实接收到相同的参数。

最后,我注意到您使用了Delphi代码中的runas谓词。也许这就是问题所在。也许你不应该抬高。


几句旁白:

    Delphi程序中的忙循环是浪费的。您应该等待进程句柄,而不是运行忙循环。你可能希望运行一个单独的线程来保持UI的活动。
  1. 进程句柄泄露