Search code examples
delphidelphi-xe

Setting up UDL connection at runtime in Delphi


In our Delphi application we are using UDL file for storing connection properties. If UDL file is missing then I want to create it and let the user to choose the server/database and set up username/password. Then it can be saved in UDL file and used all the time when application starts. I know there is security issue here but that is how it works in my project (I am not going to change it now).

The UDL file is supposed to be in 'C:\Program Files (x86)\Common Files\system\ole db\Data Links' folder and generally it is there. But if it is missing I want to create it and let the user to set up server/database, etc. in it (it is different for every customer). I already know how to create UDL file (using CreateUDLFile function). But how to pop it up on the screen for user to complete the setup. It is supposed to be a kind of application setup which would be done only once. Now it can be done manually (by double clicking on the UDL file) but I want to automate it.

This is what I want to be pop up:

enter image description here


Solution

  • This is the answer to my question:

    procedure TdmMain.DataModuleCreate(Sender: TObject);
    var
      lDataLinkDir: String;
    begin
      lDataLinkDir := DataLinkDir;
      if not FileExists(Format('%s\MBMIS.udl',[lDataLinkDir])) then
      begin
        if Copy(lDataLinkDir, Length(lDataLinkDir) - 1, 1) <> '\' then
          lDataLinkDir := lDataLinkDir + '\';
      // Creates empty UDL datalink.
      CreateUDLFile(lDataLinkDir + 'MBMIS.udl', 'SQLOLEDB.1', '');
      // Opens up the created UDL datalink for user to complete setup.
      ShellExecuteAndWait(lDataLinkDir + 'MBMIS.udl', '');
    end;
    
    { Runs application using ShellExecuteEx and waits for completion. }
    function TdmMain.ShellExecuteAndWait(FileName: String; Params: String): Boolean;
    var
      exInfo: TShellExecuteInfo;
      Ph: DWORD;
    begin
      FillChar(exInfo, SizeOf(exInfo), 0);
      with exInfo do
      begin
        cbSize := SizeOf(exInfo);
        fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
        Wnd := GetActiveWindow();
        exInfo.lpVerb := 'open';
        exInfo.lpParameters := PChar(Params);
        lpFile := PChar(FileName);
        nShow := SW_SHOWNORMAL;
      end;
      if ShellExecuteEx(@exInfo) then
        Ph := exInfo.hProcess
      else
      begin
        ShowMessage(SysErrorMessage(GetLastError));
        Result := true;
        exit;
      end;
      while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
        Application.ProcessMessages;
      CloseHandle(Ph);
      Result := true;
    end;