0

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

pyfyc
  • 127
  • 2
  • 9
  • 1
    See if the article [here](http://delphi.cjcsoft.net/viewthread.php?tid=43151) does what you want. – MartynA Oct 01 '19 at 10:47
  • @MartynA, thanks. I saw that article but that code just creates UDL file. I already know how to do that. What I want to do is to pop up the created UDL file on the screen (just like I double click on it). – pyfyc Oct 02 '19 at 01:34
  • 1
    Create the empty .UDL file (as the link explains), and then launch the .UDL file using `ShellExecute`. That will open the dialog your image shows, which allows the user to edit it. – Ken White Oct 02 '19 at 02:00
  • Or as an alternative, include the .UDL file as a resource file inside your application. If the .UDL file isn't present when your app starts up, you can extract the resource, save it to disk, and then `ShellExecute` it for the user to edit. – Ken White Oct 02 '19 at 02:35
  • @Ken White, thanks. I managed to make it work this way. However in my case I need to use ShellExecuteEx and wait for completion. I used ShellExecuteAndWait() function for that from another thread: [link](https://stackoverflow.com/questions/4295285/how-can-i-wait-for-a-command-line-program-to-finish/4295788) – pyfyc Oct 02 '19 at 03:52

1 Answers1

1

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;
pyfyc
  • 127
  • 2
  • 9