Inno Setup: не удалось выгрузить и удалить DLL, требуемую при установке из папки {tmp} в конце установки [дубликат]

$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
    $subject = $name;
    // To send HTML mail, the Content-type header must be set.
    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= 'From:' . $email. "\r\n"; // Sender's Email
    //$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
    $template = '<div style="padding:50px; color:white;">Hello ,<br/>'
        . '<br/><br/>'
        . 'Name:' .$name.'<br/>'
        . 'Email:' .$email.'<br/>'
        . '<br/>'
        . '</div>';
    $sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
    // Message lines should not exceed 70 characters (PHP rule), so wrap it.
    $sendmessage = wordwrap($sendmessage, 70);
    // Send mail by PHP Mail Function.
    mail($reciver, $subject, $sendmessage, $headers);
    echo "Your Query has been received, We will contact you soon.";
} else {
    echo "<span>* invalid email *</span>";
}
21
задан caesay 20 May 2016 в 08:16
поделиться

5 ответов

Легкий способ сделать то, что вы хотите, через AppDomain. Вы можете выгрузить AppDomain, а не начальную. Итак, решение состоит в том, чтобы создать новый AppDomain, загрузить в него управляемую DLL и затем выгрузить AppDomain.

        AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
        Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
        object d = a.CreateInstance("MyManagedDll.MyManagedClass");
        Type t = d.GetType();
        double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object[] { 1.0, 2.0 });
        AppDomain.Unload(ad);

Вот что выглядит DLL-код ...

namespace MyManagedDll
{
   public class MyManagedClass
   {
      public double Calculate(double a, double b)
      {
        return a + b;
      }
   }
}
-1
ответ дан AQuirky 21 August 2018 в 14:23
поделиться
  • 1
    Это не относится к ОП. OP хочет реализовать расширение для существующего неуправляемого приложения в .NET. OP не может создать новый AppDomain, так как он / она не контролирует процесс загрузки DLL. – Martin Prikryl 13 February 2017 в 20:26
  • 2
    Это действительно актуально. Он может попасть в управляемую DLL. Эта управляемая DLL просто создает домен приложения и загружает другую управляемую DLL, которая затем выгружается. Так что из моего ответа было то, что потребуется 2 управляемых DLL. Я просто подумал, что это очевидно. – AQuirky 14 February 2017 в 20:45
  • 3
    Да, это было очевидно. Но проблема, которую имеет OP: "DLL больше не может быть выгружена. Использование UnloadDLL (...) Inno-Setup не имеет эффекта, и файл остается заблокированным до выхода программы установки. Из-за этого установка ждет 2 секунды, а затем не удалит мой DLL-файл из временного каталога (или установочного каталога). Фактически, он действительно остается там, пока кто-то не очистит диск. & Quot; - что ваш ответ не может решить эту проблему. – Martin Prikryl 14 February 2017 в 20:59

Как было предложено в других ответах, вы можете запустить отдельный процесс в конце установки, который позаботится об очистке после завершения процессов установки.

Простым решением является создание рекламно- hoc пакетный файл, который циклически до тех пор, пока DLL-файл не будет удален, а затем удалит временную папку (теперь пустую) и сам.

procedure DeinitializeSetup();
var
  FilePath: string;
  BatchPath: string;
  S: TArrayOfString;
  ResultCode: Integer;
begin
  FilePath := ExpandConstant('{tmp}\MyAssembly.dll');
  if not FileExists(FilePath) then
  begin
    Log(Format('File %s does not exist', [FilePath]));
  end
    else
  begin
    BatchPath :=
      ExpandConstant('{%TEMP}\') +
      'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
    SetArrayLength(S, 7);
    S[0] := ':loop';
    S[1] := 'del "' + FilePath + '"';
    S[2] := 'if not exist "' + FilePath + '" goto end';
    S[3] := 'goto loop';
    S[4] := ':end';
    S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
    S[6] := 'del "' + BatchPath + '"';
    if not SaveStringsToFile(BatchPath, S, False) then
    begin
      Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
    end
      else
    if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
    begin
      Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
    end
      else
    begin
      Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
    end;
  end;
end;
2
ответ дан Martin Prikryl 21 August 2018 в 14:23
поделиться

Как предложено в этом проекте кода. Статья: https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx

вызывает cmd с аргументами, как показано ниже .

 Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);

Но в основном, как предложил @Sean, убедитесь, что вы не дождались выхода cmd.exe в свой скрипт.

1
ответ дан Mohammedparvez Shaikh 21 August 2018 в 14:23
поделиться
  • 1
    Чтобы это было надежным, вам нужно дождаться завершения процесса установки. Ожидание фиксированного времени не является надежным. – Martin Prikryl 8 January 2017 в 11:24

Вы можете добавить пакетный скрипт (в виде запуска cmd -c), который должен быть выполнен в конце установки, который ждет, когда файл будет удален и удалит его. (просто убедитесь, что параметр inno не дождался завершения процесса cmd)

Вы также можете сделать свою установленную программу обнаруженной и удалить ее при первом выполнении.

1
ответ дан Sean K 21 August 2018 в 14:23
поделиться

Не отвечая на свой вопрос, не можете ли вы просто пометить DLL, которая будет удалена при следующем перезапуске компьютера?

0
ответ дан zmbq 21 August 2018 в 14:23
поделиться
  • 1
    Если я не ошибаюсь, вы должны добавить это как комментарий к самому вопросу – Matías Fidemraizer 7 February 2015 в 23:19
  • 2
    Хотя это возможный подход, его не идеальный вариант, не отвечает на вопрос и не объясняет причину, по которой выгрузка DLL не выполняется в первую очередь. – caesay 20 May 2016 в 00:38
Другие вопросы по тегам:

Похожие вопросы: