C# Удалить запускаемый файл

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by fire64, 16 Aug 2013.

  1. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Пишу функцию обновления.

    Алгоритм такой:
    1. Проверяем на сервере наличие обновлений.
    2. Если обновление имеется, то скачивается во временную папку.
    3. Программа удаляет свой запускаемый файл и перемещает на его место обновленную версию.

    Вопрос в чем, как не закрывая программу удалить её файл, затем переместить временный файл и запустить его?
     
    #1 fire64, 16 Aug 2013
    Last edited: 16 Aug 2013
  2. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    что то я ничего не понял. ты хочешь слить апдейт, удалить файл запущенной программы, закрыть запущенную программу и запустить апдейт? как то это странно. выноси апдейтер в отдельный исполняемый файл, из него шли сигнал на завершение запущенной программе, копируй апдейт и запускай.
     
  3. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    я тоже не совсем понял - а что ты хочешь? то бишь если есть апдей - то удалить старый исполняемый файл и заменить на новый?
     
  4. Artanis

    Artanis New Member

    Joined:
    17 Sep 2011
    Messages:
    35
    Likes Received:
    4
    Reputations:
    1
    Давно не заходил сюда... Эх.

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

    Даже если это реализовать то без закрытия текущей программы, новую не открыть (заменив текущую незаметно). Если только она в фоновом режиме считает новые конфигурации, что возможно и есть обновление.
     
  5. -=Cerberus=-

    -=Cerberus=- κρυπτός γράφω

    Joined:
    29 Apr 2012
    Messages:
    1,321
    Likes Received:
    930
    Reputations:
    391
    Папка
    -Старый.exe
    -Новый.exe

    старой прогой скачиваете новый в папку с старым, меняете автозагрузку на новый.
    В новом код удаления старого файла.

    это вариант с обновой после рестарта

    без оной(нашел в интенетах)

    PHP:

    Изюминка кода в том
    что запущенная апликация все еще работает в памятиа файл который ее запустил убит.

    using System;
    using System.Runtime.InteropServices;
    using System.Text;


    [
    StructLayout(LayoutKind.Sequential)]
    struct SHELLEXECUTEINFO
    {
     public 
    uint cbSize;           // размер структуры
     
    public uint fMask;            // маска, указывающая
     
    public IntPtr hwnd
     public 
    string lpVerb;         // команда
     
    public string lpFile;         // имя файла
     
    public string lpParameters;   // параметры командной строки
     
    public IntPtr lpDirectory;    // текущая директория
     
    public int nShow;              // параметр, указывающий, как будет показано приложение при открытии.
     
    public IntPtr hInstApp;     // сюда будет записан hInstance приложения
     
     // Optional members 
     
    public IntPtr lpIDList;        // IDL, определяющий файл для выполнения
     
    public string lpClass;         // имя класса файла или GUID
     
    public IntPtr hkeyClass;         // дескриптор ключа в реестре для класса файла
     
    public uint dwHotKey;         // горячая клавиша
     
    public IntPtr hIcon;           // иконка для класса файла
     
    public IntPtr hProcess;        // дескриптор процесса
    }


    /*

    struct _SHELLEXECUTEINFO
    {
     DWORD cbSize;           // размер структуры
     ULONG fMask;            // маска, указывающая
     HWND hwnd; 
     LPCTSTR lpVerb;         // команда
     LPCTSTR lpFile;         // имя файла
     LPCTSTR lpParameters;   // параметры командной строки
     LPCTSTR lpDirectory;    // текущая директория
     int nShow;              // параметр, указывающий, как будет показано приложение при открытии.
     HINSTANCE hInstApp;     // сюда будет записан hInstance приложения
     
     // Optional members 
     LPVOID lpIDList;        // IDL, определяющий файл для выполнения
     LPCSTR lpClass;         // имя класса файла или GUID
     HKEY hkeyClass;         // дескриптор ключа в реестре для класса файла
     DWORD dwHotKey;         // горячая клавиша
     HANDLE hIcon;           // иконка для класса файла
     HANDLE hProcess;        // дескриптор процесса
    }   
    */

    namespace kill_f
    {
     

     public class 
    selfdel
     
    {

      private 
    int MAX_PATH  =260;
      private 
    int SW_HIDE =0;
      private 
    uint SEE_MASK_NOCLOSEPROCESS 64;
      private 
    uint REALTIME_PRIORITY_CLASS=256;
      private 
    int THREAD_PRIORITY_TIME_CRITICAL=15;
      private 
    uint IDLE_PRIORITY_CLASS=64;
      private 
    int SHCNE_DELETE=4;
      private 
    uint SHCNF_PATH=1;//5
      
    private uint NORMAL_PRIORITY_CLASS=32;
      private 
    int THREAD_PRIORITY_NORMAL=0;

      [
    DllImport("kernel32.dll"SetLastError=true)]
      [
    PreserveSig]
      public static 
    extern uint GetModuleFileName
       
    (
       [
    In]
       
    IntPtr hModule,
       [
    Out
       
    StringBuilder lpFilename
       [
    In]
       [
    MarshalAs(UnmanagedType.U4)]
       
    int nSize
       
    );
      [
    DllImport("kernel32.dll"SetLastError=trueCharSet=CharSet.Auto)]
      static 
    extern int GetShortPathName(
       
    string lpszLongPath
       [
    OutStringBuilder lpszShortPath
       
    int cchBuffer);
      [
    DllImport("kernel32.dll")]
      static 
    extern uint GetEnvironmentVariable(string lpName,[OutStringBuilder lpBufferint nSize);
    //  [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
     // static extern IntPtr lstrcpy([Out] StringBuilder lpString1, string lpString2);
     // [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
     // static extern IntPtr lstrcat(StringBuilder lpString1, string lpString2);
    [DllImport("kernel32.dll")]
      static 
    extern bool SetPriorityClass(IntPtr hProcessuint dwPriorityClass);
      [
    DllImport("kernel32.dll")]
     
    // static extern IntPtr GetCurrentProcess();
     // [DllImport("kernel32.dll")]
      
    static extern bool SetThreadPriority(IntPtr hThreadint nPriority);
      [
    DllImport("kernel32.dll")]
      static 
    extern IntPtr GetCurrentThread();
      [
    DllImport("shell32.dll")]
      static 
    extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
      [
    DllImport("kernel32.dll")]
      static 
    extern bool SetProcessPriorityBoost(IntPtr hProcessbool DisablePriorityBoost);
      [
    DllImport("shell32.dll")]
      static 
    extern void SHChangeNotify(int wEventIduint uFlagsIntPtr dwItem1,IntPtr dwItem2);


      public 
    selfdel()
      {
      }

      public 
    bool SelfDelete()
      {
       
    SHELLEXECUTEINFO sei=new SHELLEXECUTEINFO();

       
    StringBuilder szModule=new StringBuilder(MAX_PATH); 
       
    StringBuilder szComspec= new StringBuilder(MAX_PATH);
       
    StringBuilder szParams = new StringBuilder(MAX_PATH);

       
    // get file path names:
       
    if((GetModuleFileName(IntPtr.Zero,szModule,MAX_PAT*H)!=0) &&
        (
    GetShortPathName(szModule.ToString(),szModule,MAX*_PATH)!=0) &&
        (
    GetEnvironmentVariable("COMSPEC",szComspec,MAX_PA*TH)!=0))
       {
        
    // set command shell parameters
        
    szParams.Append("/c del ");    //lstrcpy(szParams,"/c del ");
        
    szParams.Append(szModule.ToString()); //lstrcat(szParams, szModule.ToString());
        
    szParams.Append(" > nul");    //   lstrcat(szParams, " > nul");

        // set struct members
        
    sei.cbSize       = (uint)Marshal.SizeOf(sei);
        
    sei.hwnd         IntPtr.Zero;
        
    sei.lpVerb       "Open";
        
    sei.lpFile       szComspec.ToString();
        
    sei.lpParameters szParams.ToString();
        
    sei.lpDirectory  IntPtr.Zero;
        
    sei.nShow        SW_HIDE;
        
    sei.fMask        SEE_MASK_NOCLOSEPROCESS;

        
    // increase resource allocation to program
        //SetPriorityClass(GetCurrentProcess(),REALTIME_PR*IORITY_CLASS);
        
    SetPriorityClass(System.Diagnostics.Process.GetCur*rentProcess().Handle,REALTIME_PRIORITY_CLASS);
        
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORI*TY_TIME_CRITICAL);

        
    // invoke command shell
        
    if(ShellExecuteEx(ref sei))
        {
         
    // suppress command shell process until program exits
         
    SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS)*;
         
    SetProcessPriorityBoost(sei.hProcess,true);

         
    // notify explorer shell of deletion
         
    SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,Marshal.Str*ingToHGlobalAnsi(szModule.ToString()),IntPtr.Zero)*;
         return 
    true;
        }
        else 
    // if error, normalize allocation
        
    {
         
    //SetPriorityClass(GetCurrentProcess(),NORMAL_PRIO*RITY_CLASS);
         
    SetPriorityClass(System.Diagnostics.Process.GetCur*rentProcess().Handle,NORMAL_PRIORITY_CLASS);
         
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORI*TY_NORMAL);
        }
       }
       return 
    false;
      }
     }
    }