Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
Надо заменить некоторые системные файлы (dll).
(очень прошу не обсуждать здесь плохо это, хорошо ли, зачем и т.д. есть такое слово НАДО).

С парочкой файлов у меня спотык следующего рода.
Владельца взял, права на удаление/замену взял.
Но недостаточно.

Copying... Failed. Error 57 (Процесс не может получить доступ к файлу "C:\WINDOWS\system32\blablabla.dll", так как этот файл используется другим процессом.)

Ручками проблема лечится так:
1)
Process Explorer
Find -> Find Handle or DLL
Handle or DLL substring: blablabla.dll
(здесь можно ввести полный путь C:\WINDOWS\system32\blablabla.dll)
Находит типа
Process=RuntimeBroker.exe PID=9876
2) Alt+CTRL+Del -> Диспетчер задач
->Подробности
Находим этот самый
RuntimeBroker.exe PID=9876 (выполняется от имени "тек. пользователя")
и делаем ему "Снять задачу".

Ну т.е. мои два вопроса
Как программно
1) найти удерживающий PID (ну или список кто использует)
2) грохнуть тот процесс

P.S. Делать отложенную "замену при перезагрузке", м.б. вариант но еще не факт что получится, и главное не очень хочется.
В общем, считаю, под свою ответственность, что описанная ручная процедура подойдет.
Конкретно RuntimeBroker.exe, я так понял, что-то связанное с телеметрией-"слежкой" в Win10, грохается он безобидно, после перезагрузки компа опять принимается за свое закусывание, ИМХО считаю грохнуть его относит. безобидно.

Или м.б. кто знает имя службы этого RuntimeBroker.exe?
(если это служба конечно)
чтоб ее типа net stop на момент замены, потом net start.
13 апр 18, 01:19    [21335286]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
Вот вроде по теме нашел:
How do I find out which process has a file open?
13 апр 18, 02:16    [21335308]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
pation
Member

Откуда: Москва
Сообщений: 4437
Дмитрий77,

наймспейс System.Diagnostics
смотри классы Process и иже с ним
14 апр 18, 01:08    [21338439]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Dima T
Member

Откуда:
Сообщений: 12233
Перебираешь все процессы, в каждом все модули. https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686701(v=vs.85).aspx
14 апр 18, 11:18    [21338796]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
Ну допустим PID(ы) я нашел по технологии Restart Manager.
(название ф-ции неудачное, но это не конечный вариант)
 Public Function ReplaceBlockedFile(ByVal file_name As String, ByRef err_text As String) As Boolean
    ReplaceBlockedFile = True

    Dim pSessionHandle As Integer
    Dim strSessionKey As String = StrDup(255, Chr(0))
    Dim dwRes As Integer
    dwRes = RmStartSession(pSessionHandle, 0, strSessionKey)
    If dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmStartSession Error " & RaiseAPIErrorByNumber(dwRes)
      GoTo ToExit
    End If
    If InStr(strSessionKey, Chr(0)) > 0 Then
      strSessionKey = Strings.Left(strSessionKey, InStr(strSessionKey, Chr(0)) - 1)
    End If
    Debug.Print("pSessionHandle=" & CStr(pSessionHandle) & ";strSessionKey=" & strSessionKey)

    Dim rgsFilenames As String() = New String() {file_name}
    dwRes = RmRegisterResources(pSessionHandle, 1, rgsFilenames, 0, Nothing, 0, Nothing)
    If dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmRegisterResources Error " & RaiseAPIErrorByNumber(dwRes)
      GoTo ToExit
    End If

    Dim pnProcInfoNeeded As Integer = 0
    Dim pnProcInfo As Integer = 0
    Dim lpdwRebootReasons As RM_REBOOT_REASON = RM_REBOOT_REASON.RmRebootReasonNone
    ' the first call to RmGetList() returns the total number of processes
    dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, Nothing, lpdwRebootReasons)
    If dwRes = ERROR_MORE_DATA Then
      ' Create an array to store the processes results
      Dim processInfo As RM_PROCESS_INFO() = New RM_PROCESS_INFO(pnProcInfoNeeded - 1) {}
      pnProcInfo = pnProcInfoNeeded
      ' Get the list
      dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, processInfo, lpdwRebootReasons)
      If dwRes <> ERROR_SUCCESS Then
        ReplaceBlockedFile = False
        err_text = "RmGetList(2) Error " & RaiseAPIErrorByNumber(dwRes)
        GoTo ToExit
      End If

      'Enumerate all of the results
      For i As Integer = 0 To pnProcInfo - 1
        MsgBox(processInfo(i).Process.dwProcessId)
      Next

    ElseIf dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmGetList(1) Error " & RaiseAPIErrorByNumber(dwRes)
      GoTo ToExit
    End If



ToExit:
    dwRes = RmEndSession(pSessionHandle)
    If dwRes <> ERROR_SUCCESS Then
      Debug.Print("RmStartSession Error " & RaiseAPIErrorByNumber(dwRes))
    End If
  End Function


В выделенной строчке перечисляются PID-ы. (могу вывести имя (имена) блокирующего процесса и т.п.)
А чем грохать PID?
Ну кроме вот этого.
taskkill /pid <PID> /f

Restart Manager вроде сам умеет перестартовывать в каких-то случаях, но похоже не мой вариант (processInfo(i).bRestartable =false).
Поэтому нужен грубый вариант.
16 апр 18, 02:46    [21341381]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
Дмитрий77,

В чём проблема переименовать DLL, который запущен и скопировать новый?
16 апр 18, 03:03    [21341385]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
Хотя может и не сработать, но попробовать можно )
16 апр 18, 03:04    [21341386]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
Дмитрий77
А чем грохать PID?


https://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682108(v=vs.85).aspx
16 апр 18, 03:07    [21341387]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
hVostt
Дмитрий77,

В чём проблема переименовать DLL, который запущен и скопировать новый?

Во-первых может не сработать, во-вторых мусор, его потом убирать надо.

Ну насчет TerminateProcess наверно прав.
Накидал вот ф-цию.
  Public Function kill_by_pid(ByVal pid As Integer, ByRef err_text As String) As Boolean
    Dim handle As IntPtr
    handle = OpenProcess(SYNCHRONIZE Or PROCESS_TERMINATE, True, pid)
    If handle = IntPtr.Zero Then
      err_text = "OpenProcess Error " & RaiseAPIError()
      Return False
    End If

    If TerminateProcess(handle, 0) = False Then
      err_text = "TerminateProcess Error " & RaiseAPIError()
      Return False
    Else
      Return True
    End If
  End Function

Ну здесь играться надо еще. Мне б например очень бы не хотелось грохнуть например explorer случайно.
Но это проверяется.

processInfo(i).ApplicationType

  Public Enum RM_APP_TYPE
    RmUnknownApp = 0
    RmMainWindow = 1
    RmOtherWindow = 2
    RmService = 3
    RmExplorer = 4
    RmConsole = 5
    RmCritical = 1000
  End Enum

Хотя в моем случае мешает похоже только некий RuntimeBroker.exe, которого если грохнуть не убудет.
16 апр 18, 03:34    [21341390]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Dima T
Member

Откуда:
Сообщений: 12233
Дмитрий77
А чем грохать PID?

TerminateProcess()
Для получения хэндла OpenProcess()
16 апр 18, 07:18    [21341419]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
schi
Member

Откуда: Москва
Сообщений: 2483
Дмитрий77
Надо заменить некоторые системные файлы (dll).


Вирусописателей давить. Советчиков тоже.
16 апр 18, 10:25    [21341681]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 2223
schi
Дмитрий77
Надо заменить некоторые системные файлы (dll).


Вирусописателей давить. Советчиков тоже.


вы можете сразу определить вирусописателей и их советчиков, которых давить собрались?
поделитесь знанием
16 апр 18, 10:29    [21341697]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
Dima T
Дмитрий77
А чем грохать PID?

TerminateProcess()
Для получения хэндла OpenProcess()

Дим, ну я код то о чем говоришь уже привел (на один пост выше твоего поста).
Но TerminateProcess() это грубый путь.
Коль я уж подписался на Restart Manager, он сам все делает.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa373682(v=vs.85).aspx
http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx
RmShutdown/RmRestart рулят
    ...
    Dim pnProcInfoNeeded As Integer = 0
    Dim pnProcInfo As Integer = 0
    Dim lpdwRebootReasons As RM_REBOOT_REASON = RM_REBOOT_REASON.RmRebootReasonNone
    ' the first call to RmGetList() returns the total number of processes
    dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, Nothing, lpdwRebootReasons)
    If dwRes = ERROR_MORE_DATA Then
      ' Create an array to store the processes results
      Dim processInfo As RM_PROCESS_INFO() = New RM_PROCESS_INFO(pnProcInfoNeeded - 1) {}
      pnProcInfo = pnProcInfoNeeded
      ' Get the list
      dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, processInfo, lpdwRebootReasons)
      If dwRes <> ERROR_SUCCESS Then
        ReplaceBlockedFile = False
        err_text = "RmGetList(2) Error " & RaiseAPIErrorByNumber(dwRes)
        GoTo ToExit
      End If

      'Enumerate all of the results
      For i As Integer = 0 To pnProcInfo - 1
        MsgBox(processInfo(i).strAppName)
        'If kill_by_pid(processInfo(i).Process.dwProcessId, err_text) = False Then
        '  ReplaceBlockedFile = False
        '  GoTo ToExit
        'End If
      Next

      'https://msdn.microsoft.com/en-us/library/windows/desktop/aa373682(v=vs.85).aspx
      'http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx

      If lpdwRebootReasons <> RM_REBOOT_REASON.RmRebootReasonNone Then
        ' Restart Manager cannot mitigate a reboot. 
        ' We goes to the clean up. The caller may want   
        ' to add additional code to handle this scenario.
        ReplaceBlockedFile = False
        err_text = "Error. Applications can not be stopped."
        GoTo ToExit
      End If

      ' Shut down all running instances of affected applications and services.
      dwRes = RmShutdown(pSessionHandle, RmForceShutdown, Nothing)
      If dwRes <> ERROR_SUCCESS Then
        ReplaceBlockedFile = False
        err_text = "RmShutdown Error " & RaiseAPIErrorByNumber(dwRes)
        GoTo ToExit
      End If

      MsgBox("Applications stopped successfully.")

      ' An installer can now replace or update the calc executable file.
      ' CALLER CODE GOES HERE...

      ' Restart applications and services, after the files have been replaced or updated.
      dwRes = RmRestart(pSessionHandle, 0, Nothing)
      If dwRes <> ERROR_SUCCESS Then
        Debug.Print("RmRestart Error " & RaiseAPIErrorByNumber(dwRes))
        GoTo ToExit
      End If

      MsgBox("Applications restarted successfully.")
...


Т.е. не надо kill_by_pid, надо RmShutdown,
для надежности с флагом RmForceShutdown, которое так понимаю и делает kill_by_pid если уж культурно прикрыть не удалось.
Более того RmRestart еще и перестартовывает то что "грохнули".

У меня так получилось.
RuntimeBroker.exe (основной мешающий элемент) без флага RmForceShutdown таки дает "сбой при закрытии", но с флагом все OK, правда RmRestart его не перезапускает, хотя и ERROR_SUCCESS.
А вот если к примеру случайно запущен WinMail.exe (ради которого сыр-бор с заменами), то он как раз именно культурно закрывается, да потом еще культурно запускается.
Причем сами процессы можно даже не вычислять, т.е. не морочится с маршалингом структур RM_PROCESS_INFO,
достаточно того что я сделал RmRegisterResources для заменяемых файлов.
Своеобразная системная автоматика-с.

В общем допилю, думаю все OK будет.

schi
Вирусописателей давить. Советчиков тоже.

Уважаемый, вы как бы не в теме, зачем такие утверждения делать.
Вы часом не из-тех антивирус-горе писателей баблосшибателей, которые false positives тоннами плодят без зазрения совести?
16 апр 18, 15:51    [21342811]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
Как-то так. Для моих целей хватает.

+
Imports System.Runtime.InteropServices

Module m_RestartManager

  Public Const CCH_RM_MAX_APP_NAME As Integer = 255
  Public Const CCH_RM_MAX_SVC_NAME As Integer = 63

  'Restart Manager Enumerations

  Public Enum RM_APP_STATUS
    RmStatusUnknown = 0
    RmStatusRunning = 1
    RmStatusStopped = 2
    RmStatusStoppedOther = 4
    RmStatusRestarted = 8
    RmStatusErrorOnStop = 16
    RmStatusErrorOnRestart = 32
    RmStatusShutdownMasked = 64
    RmStatusRestartMasked = 128
  End Enum

  Public Enum RM_APP_TYPE
    RmUnknownApp = 0
    RmMainWindow = 1
    RmOtherWindow = 2
    RmService = 3
    RmExplorer = 4
    RmConsole = 5
    RmCritical = 1000
  End Enum

  Public Enum RM_REBOOT_REASON
    RmRebootReasonNone = 0 'A system restart is not required
    RmRebootReasonPermissionDenied = 1
    RmRebootReasonSessionMismatch = 2
    RmRebootReasonCriticalProcess = 4
    RmRebootReasonCriticalService = 8
    RmRebootReasonDetectedSelf = 16
  End Enum

  'Restart Manager Structures

  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Public Structure RM_PROCESS_INFO
    Dim Process As RM_UNIQUE_PROCESS
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCH_RM_MAX_APP_NAME + 1)>
    Dim strAppName As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCH_RM_MAX_SVC_NAME + 1)>
    Dim strServiceShortName As String
    Dim ApplicationType As RM_APP_TYPE
    Dim AppStatus As RM_APP_STATUS
    Dim TSSessionId As Integer
    <MarshalAs(UnmanagedType.Bool)>
    Dim bRestartable As Boolean
  End Structure

  <StructLayout(LayoutKind.Sequential)>
  Public Structure RM_UNIQUE_PROCESS
    Dim dwProcessId As Integer
    Dim ProcessStartTime As FILETIME
  End Structure


  'Restart Manager Callback Functions

  Public Delegate Sub RM_WRITE_STATUS_CALLBACK(ByVal nPercentComplete As Integer)

  'Restart Manager Functions

  Public Declare Function RmEndSession Lib "Rstrtmgr.dll" _
   (ByVal dwSessionHandle As Integer) As Integer
  Public Declare Unicode Function RmGetList Lib "Rstrtmgr.dll" _
   (ByVal dwSessionHandle As Integer, _
   ByRef pnProcInfoNeeded As Integer, ByRef pnProcInfo As Integer, _
   <[In], Out> ByVal rgAffectedApps As RM_PROCESS_INFO(), ByRef lpdwRebootReasons As RM_REBOOT_REASON) As Integer
  Public Declare Unicode Function RmRegisterResources Lib "Rstrtmgr.dll" _
   (ByVal dwSessionHandle As Integer, _
   ByVal nFiles As Integer, ByVal rgsFilenames As String(), _
   ByVal nApplications As Integer, ByVal rgApplications As RM_UNIQUE_PROCESS(), _
   ByVal nServices As Integer, ByVal rgsServiceNames As String()) As Integer
  Public Declare Function RmRestart Lib "Rstrtmgr.dll" _
   (ByVal dwSessionHandle As Integer, ByVal dwRestartFlags As Integer, ByVal fnStatus As RM_WRITE_STATUS_CALLBACK) As Integer

  Public Const RmForceShutdown As Integer = 1
  Public Const RmShutdownOnlyRegistered = 16

  Public Declare Function RmShutdown Lib "Rstrtmgr.dll" _
   (ByVal dwSessionHandle As Integer, ByVal lActionFlags As Integer, ByVal fnStatus As RM_WRITE_STATUS_CALLBACK) As Integer

  Public Declare Unicode Function RmStartSession Lib "Rstrtmgr.dll" _
   (ByRef pSessionHandle As Integer, ByVal dwSessionFlags As Integer, _
   ByVal strSessionKey As String) As Integer


End Module



  Public Function ReplaceBlockedFile(ByVal file_name As String, ByVal file_new As String, ByRef err_text As String) As Boolean
    ' file_name -путь к заменяемому файлу
    ' file_new -файл на который заменяем

    Dim pSessionHandle As Integer
    Dim strSessionKey As String = StrDup(255, Chr(0))
    Dim dwRes As Integer
    dwRes = RmStartSession(pSessionHandle, 0, strSessionKey)
    If dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmStartSession Error " & RaiseAPIErrorByNumber(dwRes)
      AddLogRestore("  Calling RmStartSession... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
      GoTo ToExit
    End If
    If InStr(strSessionKey, Chr(0)) > 0 Then
      strSessionKey = Strings.Left(strSessionKey, InStr(strSessionKey, Chr(0)) - 1)
    End If
    Debug.Print("pSessionHandle=" & CStr(pSessionHandle) & ";strSessionKey=" & strSessionKey)
    AddLogRestore("  Calling RmStartSession... Done. pSessionHandle=" & CStr(pSessionHandle) & ";strSessionKey=" & strSessionKey)

    Dim rgsFilenames As String() = New String() {file_name}
    dwRes = RmRegisterResources(pSessionHandle, 1, rgsFilenames, 0, Nothing, 0, Nothing)
    If dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmRegisterResources Error " & RaiseAPIErrorByNumber(dwRes)
      AddLogRestore("  Calling RmRegisterResources... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
      GoTo ToExit
    End If
    AddLogRestore("  Calling RmRegisterResources... Done.")

    Dim pnProcInfoNeeded As Integer = 0
    Dim pnProcInfo As Integer = 0
    Dim lpdwRebootReasons As RM_REBOOT_REASON = RM_REBOOT_REASON.RmRebootReasonNone
    ' the first call to RmGetList() returns the total number of processes
    dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, Nothing, lpdwRebootReasons)
    If dwRes = ERROR_MORE_DATA Then
      AddLogRestore("  Calling RmGetList(1)... Error code: " & RaiseAPIErrorByNumber(dwRes))
      AddLogRestore("  The number of affected applications = " & CStr(pnProcInfoNeeded))
      ' Create an array to store the processes results
      Dim processInfo As RM_PROCESS_INFO() = New RM_PROCESS_INFO(pnProcInfoNeeded - 1) {}
      pnProcInfo = pnProcInfoNeeded
      ' Get the list
      dwRes = RmGetList(pSessionHandle, pnProcInfoNeeded, pnProcInfo, processInfo, lpdwRebootReasons)
      If dwRes <> ERROR_SUCCESS Then
        ReplaceBlockedFile = False
        err_text = "RmGetList(2) Error " & RaiseAPIErrorByNumber(dwRes)
        AddLogRestore("  Calling RmGetList(2)... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
        GoTo ToExit
      End If
      AddLogRestore("  Calling RmGetList(2)... Done.")

      'Enumerate all of the results
      AddLogRestore("  Affected applications:")
      For i As Integer = 0 To pnProcInfo - 1
        With processInfo(i)
          AddLogRestore("    " & .strAppName & ";PID=" & CStr(.Process.dwProcessId) & ";ApplicationType=" & .ApplicationType.ToString & ";Restartable=" & .bRestartable.ToString)
        End With
      Next

      'https://msdn.microsoft.com/en-us/library/windows/desktop/aa373682(v=vs.85).aspx
      'http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx

      If lpdwRebootReasons <> RM_REBOOT_REASON.RmRebootReasonNone Then
        ' Restart Manager cannot mitigate a reboot. 
        ' We goes to the clean up. The caller may want   
        ' to add additional code to handle this scenario.
        ReplaceBlockedFile = False
        err_text = "Error. Affected applications can not be stopped."
        AddLogRestore("  Error. Affected applications can not be stopped.")
        GoTo ToExit
      End If

      ' Shut down all running instances of affected applications and services.
      dwRes = RmShutdown(pSessionHandle, RmForceShutdown, Nothing)
      If dwRes <> ERROR_SUCCESS Then
        ReplaceBlockedFile = False
        err_text = "RmShutdown Error " & RaiseAPIErrorByNumber(dwRes)
        AddLogRestore("  Calling RmShutdown... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
        'Installers should always restart application and services using the RmRestart function even when the
        'RmShutdown function returns an error indicating that not all applications and services could be shut down.
        GoTo ToRestart
      End If
      AddLogRestore("  Calling RmShutdown... Done.")

      ' An installer can now replace or update the calc executable file.
      ' CALLER CODE GOES HERE...
      'замена файла
      AddLogRestore("  Replacing '" & file_name & "'.")
      AddLogRestore("  Copying file '" & file_new & "' to '" & file_name & "'")
      Try
        IO.File.Copy(file_new, file_name, True)
        AddLogRestore("  Copying... Done.") ' "  Copying... Done."
        ReplaceBlockedFile = True
      Catch
        ReplaceBlockedFile = False
        AddLogRestore("  Copying... Failed. Error " & Err.Number.ToString & " (" & Err.Description & ")")
      End Try

ToRestart:
      ' Restart applications and services, after the files have been replaced or updated.
      dwRes = RmRestart(pSessionHandle, 0, Nothing)
      If dwRes <> ERROR_SUCCESS Then
        Debug.Print("RmRestart Error " & RaiseAPIErrorByNumber(dwRes))
        AddLogRestore("  Calling RmRestart... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
        GoTo ToExit
      End If
      AddLogRestore("  Calling RmRestart... Done.")

    ElseIf dwRes <> ERROR_SUCCESS Then
      ReplaceBlockedFile = False
      err_text = "RmGetList(1) Error " & RaiseAPIErrorByNumber(dwRes)
      AddLogRestore("  Calling RmGetList(1)... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
      GoTo ToExit

    Else 'отсутствует affected applications, этой ситуации быть не должно, раз уж вызывали в помощь эту кухню
      AddLogRestore("  Replacing '" & file_name & "'.")
      AddLogRestore("  Copying file '" & file_new & "' to '" & file_name & "'")
      Try
        IO.File.Copy(file_new, file_name, True)
        AddLogRestore("  Copying... Done.") ' "  Copying... Done."
        ReplaceBlockedFile = True
      Catch
        ReplaceBlockedFile = False
        AddLogRestore("  Copying... Failed. Error " & Err.Number.ToString & " (" & Err.Description & ")")
      End Try
    End If

ToExit:
    dwRes = RmEndSession(pSessionHandle)
    If dwRes <> ERROR_SUCCESS Then
      AddLogRestore("  Calling RmEndSession... Failed. Error code: " & RaiseAPIErrorByNumber(dwRes))
    Else
      AddLogRestore("  Calling RmEndSession... Done.")
    End If
  End Function
17 апр 18, 02:55    [21343995]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
оффтоп: какой же таки VB.NET страшный )
17 апр 18, 06:27    [21344048]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
hVostt,

Ну ты так по мне то не суди
1) Я использую VB6 стиль деклараций и т.п. и часто использую ф-ции, которые в VB.NET пришли из VB6 (в C# их тупо нет). Привычка(с)
2) Это API, поэтому здесь вообще C-стиль в духе MSDN примеров (обработка ошибок и т.п.).

P.S. Хотя при этом я не гнушаюсь вставить например копирование через .Net - ф-цию с применением Try... Catch
17 апр 18, 14:55    [21345620]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
Дмитрий77
hVostt,

Ну ты так по мне то не суди
1) Я использую VB6 стиль деклараций и т.п. и часто использую ф-ции, которые в VB.NET пришли из VB6 (в C# их тупо нет). Привычка(с)
2) Это API, поэтому здесь вообще C-стиль в духе MSDN примеров (обработка ошибок и т.п.).

P.S. Хотя при этом я не гнушаюсь вставить например копирование через .Net - ф-цию с применением Try... Catch


Да не, мне и раньше доводилось сталкиваться с VB.NET, таки он страшный сам по себе :)
И всёж если бы ты перешёл на C#, тебе бы всяко легче было бы, вот в разы.
17 апр 18, 15:55    [21345853]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4222
hVostt
Да не, мне и раньше доводилось сталкиваться с VB.NET, таки он страшный сам по себе :)
И всёж если бы ты перешёл на C#, тебе бы всяко легче было бы, вот в разы.

Ну, тебе ж с VB6 не "доводилось сталкиваться", я так думаю.
Мне и так достаточно легко, потому что я прошел через VB6, а это определенная "школа" и навыки.
ИМХО (С), для меня "страшный сам по себе" суффикс ".Net", а не приставка "VB." но нет альтернативы.
Здесь каждому свое. Я вполне освоился писать в VB.Net так как мне надо и как у меня хорошо получается.
18 апр 18, 00:43    [21347232]     Ответить | Цитировать Сообщить модератору
 Re: Узнать PID процесса, который не дает заменить dll и грохнуть этот процесс.  [new]
hVostt
Member

Откуда:
Сообщений: 13955
Дмитрий77
Ну, тебе ж с VB6 не "доводилось сталкиваться", я так думаю.


Я на VB6 делал такое, что мне сейчас даже в страшном сне не приснится. Например, писал полноценную систему управления запасами МТР на MS Access для филиалов региона со скриптами на VB6 объёмом около 100к строк. С сервером на ASP.NET 2.0, консолидаций, выгрузками, импортом/экспортом в SAP R/3 и 1C. Давно это было.

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

Например, на C# тебе бы гораздо легче было бы находить информацию и ответы на вопросы. Опять же с ВинАПИ комфортнее работать из C#, чем из VB.NET. Когда-то VB.NET мог похвастаться лучшей поддержкой работы с COM, ровно до момента, как в C# добавили dynamic.

В общем, ИМХО. :)
18 апр 18, 17:29    [21349762]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить