Ru-Board.club
← Вернуться в раздел «Программы»

» VMware ThinApp (formerly Thinstall) 3

Автор: coherent
Дата сообщения: 05.06.2014 14:05
Artem_Butenko
Можно конечно и в песочницу. Но при этом ThinApp_FileCleaner.exe придется запускать через cmd, а это - появление консольного окна. Если скрывать окно, то нужно использовать сторонние утилиты, например hstart. А это то, что предложил SLasH пару постами выше. При запуске из песочницы варианты ExecuteExternalProcess и WshShell.Run почему-то корректно не срабатывают, по крайней мере у меня.
Автор: Artem_Butenko
Дата сообщения: 05.06.2014 14:44
coherent


Цитата:
Можно конечно и в песочницу. Но при этом ThinApp_FileCleaner.exe придется запускать через cmd, а это - появление консольного окна. Если скрывать окно, то нужно использовать сторонние утилиты, например hstart. А это то, что предложил SLasH пару постами выше. При запуске из песочницы варианты ExecuteExternalProcess и WshShell.Run почему-то корректно не срабатывают, по крайней мере у меня.


Вон оно как, не знал, не вникал в суть вопроса. Если неизбежно использование "cmd.exe" и "hstart.exe", пусть оно тогда так и будет.


Цитата:
И все же вопрос, который остался без ответа, это принципиально или просто "хотелка", чтобы именно в песочницу?


Нет, то не моя "хотелка", это неизбежная "хотелка" плагина "ThinApp_FileCleaner.exe".

Добавлено:
SLasH


Цитата:
Не проверял, написал вручную на коленке


Работает. Прошу меня извинить. Антивирус блокировал исполнение скрипта. Остался вопрос, можно ли извлекать файлы напрямую в "песочницу", не создавая в ней каталог "Progs"? А если файлы уже имеются в песочнице, то не перезаписывать их.
Автор: coherent
Дата сообщения: 05.06.2014 15:09
Artem_Butenko

Цитата:
Остался вопрос, можно ли извлекать файлы напрямую в "песочницу", не создавая в ней каталог "Progs"?

Можно. Подредактируйте пути.

Цитата:
А если файлы уже имеются в песочнице, то не перезаписывать их.

Если они не удаляются и не перезаписываются, тогда достаточно один раз при первом запуске сборки(OnFirstSanboxOwner) закинуть их в песочницу и забыть про них. А при завершении (OnLastProcessExit) только запускать ThinApp_FileCleaner.exe.
Автор: Artem_Butenko
Дата сообщения: 05.06.2014 15:14
coherent


Цитата:
Можно. Подредактируйте пути.


Пожалуйста, помогите я совсем в VBS-скриптах ноль. Сам [more=скрипт]Function OnLastProcessExit
const MegaProga = "MegaProga.exe"
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' В проекте папка "%drive_c%\Progs" с exe-шниками, которые нужно вынести наружу
const PROG_PATH = "C:\Progs"
' Часть пути из PROG_PATH без буквы диска: \Progs
Dim PROG_SUB_PATH: PROG_SUB_PATH = Mid(PROG_PATH, 3)
' Внешний cmd.exe
Dim CMD_ETERNAL: CMD_ETERNAL = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)
' В проекте "%drive_c%\Progs\hstart.exe
Dim HSTART: HSTART = PROG_PATH & "\hstart.exe"

LastSlash = InStrRev(Origin, "\")
SourcePath = Left(Origin, LastSlash)
ExeName = Mid(Origin, LastSlash + 1, Len(Origin))

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

' Внешний hstart.exe: <SandBox>\Progs\hstart.exe
Dim HSTART_EXTERNAL: HSTART_EXTERNAL = SandboxPath & PROG_SUB_PATH & "\hstart.exe"

On Error Resume Next
' Копируем папку изнутри наружу: "C:\Progs" в песочницу
If Not FSO.FolderExists(SandboxPath & PROG_SUB_PATH) Then
' xcopy /E /H /R /Y C:\Progs <Sandbox>\Progs\
cmd = CMD_ETERNAL & " /C xcopy /E /H /R /Y "& _
chr(34)& PROG_PATH &chr(34)& _
" " & _
chr(34)& SandboxPath & PROG_SUB_PATH &"\"&chr(34)
' <Sandbox>\Progs\hstart.exe /NOCONSOLE ""C:\Windows\system32\cmd.exe" /C xcopy /E /H /R /Y "C:\Progs" <Sandbox>\Progs\""
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
' Ожидаем, пока скопируется каталог PROG_PATH
Do
MySleep(1)
Loop Until FSO.FolderExists(SandboxPath & PROG_SUB_PATH)
End If

' Запуск из песочницы
cmd = CMD_ETERNAL & " /C " & chr(34)& SandboxPath & PROG_SUB_PATH &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(HSTART_EXTERNAL & " /NOCONSOLE " & chr(34) & cmd & chr(34)), 0)

End Function

'--[ Пауза ]--------------------------------------------------------------------
Function MySleep(interval)
Dim i,j
For i = 1 To 20000000*interval
j = 1
Next
End Function[/more].
Автор: coherent
Дата сообщения: 05.06.2014 15:21
Artem_Butenko
Давайте подождем SLasH. Это полностью его скрипт и будет не совсем корректно, если я его буду править.
добавлено
Плюс не совсем понятно, что делать с файлами ThinApp_FileCleaner.exe и ThinApp_FileCleaner.ini. Вынести в песочницу и запустить ThinApp_FileCleaner.exe, если там уже есть ThinApp_FileCleaner.ini, то его не перезаписывать? А что с ThinApp_FileCleaner.exe? Его удалять, когда он отработает, или он тоже остается в песочнице и его тоже не надо перезаписывать?
Автор: SLasH
Дата сообщения: 05.06.2014 15:28
Artem_Butenko 16:44 05-06-2014
Цитата:
Остался вопрос, можно ли извлекать файлы напрямую в "песочницу", не создавая в ней каталог "Progs"? А если файлы уже имеются в песочнице, то не перезаписывать их.

Можно. Нужно только отталкиваться от виртуальных путей, где лежат ваши файлы.
Пусть, к примеру, это будет виртуальный путь "C:\Program Files\Some Program Software\MegaSuperProga.exe". Это означает, что в проекте есть "%ProgramFilesDir%\Some Program Software\MegaSuperProga.exe". Тогда копирование "MegaSuperProga.exe" изнутри наружу выглядит так:

Код: ' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
cmd = CMD_ETERNAL & " /C copy ""C:\Program Files\Some Program Software\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
End If
Автор: coherent
Дата сообщения: 05.06.2014 15:44
SLasH
Чисто из любопытства, почему копирование через cmd, а не методом CopyFile?
Автор: SLasH
Дата сообщения: 05.06.2014 15:49
AVanti473 21:44 04-06-2014
Цитата:
Получается после перезагрузки стартанёт одноразовый запуск удаления папки. Ок! Но, а если нужно было наоборот, забекапить папку (если такая существовала), убрать её оттуда (опять же, если она существовала) перед запуском программы, удалить папку появившуюся в следствии работы портабельной программы, и вернуть забекапленную на место после перезагрузки? Возможно?

Давайте ставить реальное ТЗ.
Т.к. приходится самому догадываться, как работает ваша сборка.
Пусть будет абстрактный "Some.exe" который делает ту функцию, которая вам нужна и после своей работы жёстко перезагружает машину.
Тогда, если я правильно понял, что вам нужно, то действия такие:
до запуска "Some.exe":
1) забэкапить папку, в которую потом будет что-то писать "Some.exe". Как я понял эта папка "%AppData%\Local\ChemTable Software\Reg Organizer"
2) удалить папку "%AppData%\Local\ChemTable Software\Reg Organizer"
3) записываем в реальную систему скрипт, который будет восстанавливать всё, что нужно
после запуска "Some.exe" и перезагрузки запускаетя скрипт, который:
1) удаляет папку, которая появляется в следствии работы "Some.exe". Напишите полный путь, какую папку нужно удалять. Или это всё та же папка "%AppData%\Local\ChemTable Software\Reg Organizer" ?
2) возвращает забэкапленную папку "%AppData%\Local\ChemTable Software\Reg Organizer" обратно

Добавлено:
coherent 17:44 05-06-2014
Цитата:
Чисто из любопытства, почему копирование через cmd, а не методом CopyFile

Изначально я свой пример писал для копирования каталога через xcopy, оттуда и оставил xcopy или copy.
А с методом CopyFile не тестировал. Сожет ли он изнутри наружу копировать. Нужно тестировать...
Автор: Artem_Butenko
Дата сообщения: 05.06.2014 16:01
SLasH


Цитата:
' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
    cmd = CMD_ETERNAL & " /C copy ""C:\Program Files\Some Program Software\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
    ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
    Do
        MySleep(1)
    Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
End If


Как я понял это только часть изложенного Вами выше скрипта. Пожалуйста, если не трудно, можно увидеть весь скрипт целиком. Сам боюсь при редактировании сделаю море ошибок. Повторюсь, всего файлов два: "MegaSuperProga.ini" и "MegaSuperProga.exe". При этом первым экспортируется в "песочницу" файл "MegaSuperProga.ini", а затем только "MegaSuperProga.exe", и производится запуск последнего. Ожидаем завершения работы "MegaSuperProga.exe" и удаляем его. "Инишник" ("MegaSuperProga.ini") оставляем в "песочнице", при повторном запуске осуществляем проверку на наличие "MegaSuperProga.ini" и "MegaSuperProga.exe" в каталоге "песочницы". Если файлы там уже имеются, не выносим их из виртуальной среды. Пожалуйста, помогите довести скрипт до окончательного варианта. Очень Вам благодарен.

Добавлено:
Отредактировал скрипт [more=таким образом]Function OnLastProcessExit
const MegaProga = "MegaSuperProga.exe"
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' В проекте папка "%drive_c%\Progs" с exe-шниками, которые нужно вынести наружу
const PROG_PATH = "C:\Program Files\Data"
' Часть пути из PROG_PATH без буквы диска: \Progs
Dim PROG_SUB_PATH: PROG_SUB_PATH = Mid(PROG_PATH, 3)
' Внешний cmd.exe
Dim CMD_EXTERNAL: CMD_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)
' В проекте "%drive_c%\Progs\hstart.exe
Dim HSTART: HSTART = PROG_PATH & "\hstart.exe"

LastSlash = InStrRev(Origin, "\")
SourcePath = Left(Origin, LastSlash)
ExeName = Mid(Origin, LastSlash + 1, Len(Origin))

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

' Внешний hstart.exe: <SandBox>\Progs\hstart.exe
Dim HSTART_EXTERNAL: HSTART_EXTERNAL = SandboxPath & PROG_SUB_PATH & "\hstart.exe"

On Error Resume Next

' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.ini") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.ini"" " &chr(34)& SandboxPath & "\MegaSuperProga.ini"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.ini")
End If
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
End If

' Запуск из песочницы
cmd = CMD_EXTERNAL & " /C " & chr(34)& SandboxPath & PROG_SUB_PATH &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(HSTART_EXTERNAL & " /NOCONSOLE " & chr(34) & cmd & chr(34)), 0)

End Function

'--[ Пауза ]--------------------------------------------------------------------
Function MySleep(interval)
Dim i,j
For i = 1 To 20000000*interval
j = 1
Next
End Function[/more]. Думаю не совсем все я сделал правильно.

Добавлено:
Файлы извлекаются, только вот запуск исполняемого файла не происходит. Еще одно последнее пожелание, хотелось бы увидеть вариант скрипта с ожиданием завершения процесса "MegaSuperProga.exe" и без ожидания завершения процесса.
Автор: AVanti473
Дата сообщения: 05.06.2014 16:37

Цитата:
Давайте ставить реальное ТЗ.


Абсолютно с Вами согласен! Вы очень хорошо всё написали, ошибка только в пути к папке!
Не "%AppData%\Local\ChemTable Software\Reg Organizer
а "%AppData%\Local\ChemTable Software

Вообще, замечательно, что Вы уточнили, потому что я со вчерашнего дня думаю куда же должен делаться бэкап!!! Прога то специфическая, по чистке реестра и дисков, поэтому просто может сожрать бекап при автоматической чистке и нечего будет восстанавливать... Но, всё по порядку, сперва порядок действий:

Действия такие:
до запуска "RegOrganizer.exe":
1) Забэкапить папку, в которую потом будет что-то писать "RegOrganizer.exe". Эта папка "%AppData%\Local\ChemTable Software" (если конечно она уже существует в системе)
2) Удалить папку "%AppData%\Local\ChemTable Software"
3) Записываем в реальную систему скрипт, который будет восстанавливать всё, что нужно!
После запуска "RegOrganizer.exe" и перезагрузки
Запускаетя скрипт, который:
1) Удаляет папку, которая появляется в следствии работы "RegOrganizer.exe" (если такая появилась). Это всё та же папка "%AppData%\Local\ChemTable Software"
2) Возвращает забэкапленную папку "%AppData%\Local\ChemTable Software" обратно.

Теперь о том, где хранить бекап. В любом месте на диске опасно, ведь, в силу функционала самой программы, при автоматической чистке дисков можно весь бекап удалить! Наверное, надёжнее будет в папке с песочницей программы, так как даже идиот додумается не сносить файлы песочницы при чистке дисков...

P.S. Я и вправду никак не могу понять, почему при нахождении папки "%AppData%\Local\ChemTable Software" в виртуале, не работает функция оптимизации реестра! Ну не стал же бы разработчик программы (тем более версия 2009 года, тогда и портабельными сборками сравнительно мало занимались) защищать именно эту функцию от работы в виртуале?! Ставил уже изоляцию и Full и WriteCopy, но всё равно, как только папка оказывается в песочнице, функция оптимизации сообщает что с реестром всё в порядке. Стоит только выкинуть папку %Local AppData% из проекта, в реальной системе появляется папка "%AppData%\Local\ChemTable Software" и реестр оптимизируется нормально, с последующей автоматической перезагрузкой! Всё это по меньшей мере странно и теперь требует навороченных скриптов с бекапами... Надеюсь, хоть так получиться!
Автор: SLasH
Дата сообщения: 05.06.2014 16:48
AVanti473 18:37 05-06-2014
Цитата:
Я и вправду никак не могу понять, почему при нахождении папки "%AppData%/Local/ChemTable Software" в виртуале, не работает функция оптимизации реестра

Возможно так была построена логика программы. Если эта папка существует, то реестр уже дафрагментировался.

Добавлено:
Artem_Butenko 18:01 05-06-2014
Цитата:
Отредактировал скрипт таким образом [?]. Думаю не совсем все я сделал правильно.

Всё правильно.

Цитата:
Файлы извлекаются, только вот запуск исполняемого файла не происходит

Тогда 2 варианта:
1) пробуете сами разобраться запустив без hstart и увидев, что сообщает консоль:

Код: cmd = CMD_EXTERNAL & " /K " & chr(34)& SandboxPath & PROG_SUB_PATH &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(cmd), 0)
Автор: Artem_Butenko
Дата сообщения: 05.06.2014 17:00
Пробовал еще [more=вариант]Function OnLastProcessExit
const MegaProga = "MegaSuperProga.exe"
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' В проекте папка "%drive_c%\Progs" с exe-шниками, которые нужно вынести наружу
const PROG_PATH = "C:\Program Files\Data"
' Часть пути из PROG_PATH без буквы диска: \Progs
Dim PROG_SUB_PATH: PROG_SUB_PATH = Mid(PROG_PATH, 3)
' Внешний cmd.exe
Dim CMD_EXTERNAL: CMD_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)
' В проекте "%drive_c%\Progs\hstart.exe
Dim HSTART: HSTART = PROG_PATH & "\hstart.exe"

LastSlash = InStrRev(Origin, "\")
SourcePath = Left(Origin, LastSlash)
ExeName = Mid(Origin, LastSlash + 1, Len(Origin))

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

' Внешний hstart.exe: <SandBox>\Progs\hstart.exe
Dim HSTART_EXTERNAL: HSTART_EXTERNAL = SandboxPath & "\hstart.exe"

On Error Resume Next

' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.ini") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.ini"" " &chr(34)& SandboxPath & "\MegaSuperProga.ini"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.ini")
End If
If Not FSO.FileExists(SandboxPath & "\hstart.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\hstart.exe"" " &chr(34)& SandboxPath & "\hstart.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\hstart.exe")
End If
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
End If

' Запуск из песочницы
cmd = CMD_EXTERNAL & " /C " & chr(34)& SandboxPath &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(HSTART_EXTERNAL & " /NOCONSOLE " & chr(34) & cmd & chr(34)), 0)

End Function

'--[ Пауза ]--------------------------------------------------------------------
Function MySleep(interval)
Dim i,j
For i = 1 To 20000000*interval
j = 1
Next
End Function[/more]. Главный исполняемый ("MegaSuperProga.exe") файл не запускается.

Добавлено:
SLasH

[more=Рабочий скрипт]Function OnLastProcessExit
const MegaProga = "MegaSuperProga.exe"
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' В проекте папка "%drive_c%\Progs" с exe-шниками, которые нужно вынести наружу
const PROG_PATH = "C:\Program Files\Data"
' Часть пути из PROG_PATH без буквы диска: \Progs
Dim PROG_SUB_PATH: PROG_SUB_PATH = Mid(PROG_PATH, 3)
' Внешний cmd.exe
Dim CMD_EXTERNAL: CMD_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)
' В проекте "%drive_c%\Progs\hstart.exe
Dim HSTART: HSTART = PROG_PATH & "\hstart.exe"

LastSlash = InStrRev(Origin, "\")
SourcePath = Left(Origin, LastSlash)
ExeName = Mid(Origin, LastSlash + 1, Len(Origin))

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

' Внешний hstart.exe: <SandBox>\Progs\hstart.exe
Dim HSTART_EXTERNAL: HSTART_EXTERNAL = SandboxPath & "\hstart.exe"

On Error Resume Next

' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.ini") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.ini"" " &chr(34)& SandboxPath & "\MegaSuperProga.ini"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.ini")
End If
If Not FSO.FileExists(SandboxPath & "\hstart.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\hstart.exe"" " &chr(34)& SandboxPath & "\hstart.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\hstart.exe")
End If
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
End If

' Запуск из песочницы
cmd = CMD_EXTERNAL & " /C " & chr(34)& SandboxPath &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(HSTART_EXTERNAL & " /NOCONSOLE " & chr(34) & cmd & chr(34)), 0)

End Function

'--[ Пауза ]--------------------------------------------------------------------
Function MySleep(interval)
Dim i,j
For i = 1 To 20000000*interval
j = 1
Next
End Function[/more]. Только не пойму, почему "MegaSuperProga.exe" стартует несколько раз? А если точнее четыре раза, но только при первом запуске. Пожалуйста, помогите исправить ошибку.
Автор: SLasH
Дата сообщения: 05.06.2014 17:42
Artem_Butenko
Я уже писал, что ф. OnLastProcessExit запускается несколько раз подряд - отсюда все и косяки.
Это баг и нужно репортить его в VMware.
А пока баг иммет место быть, то нужно кадое действие проверять. Т.е. если нужно запустить процесс из OnLastProcessExit, то нужно сначала проверить, нет ли среди списка процессов уже запущенного процесса.
Из-за этого бага скрипты приходится писать навороченные с кучей проверок.
Пробуйте разбираться, с работой виндового tasklist и написанием BAT-ника для проверки на запуск вашего процесса.
Автор: AVanti473
Дата сообщения: 05.06.2014 19:20

Цитата:
Возможно так была построена логика программы. Если эта папка существует, то реестр уже дафрагментировался.


Сомнительно. Ведь сборку для теста я запускаю на практически чистой системе, где никогда не было установленной этой программы. Папка создаётся с нуля! Только если она создаётся в реальной системе, то всё работает, а если в песочнице, то увы! Больше похоже на очередной косяк с ThinApp. Хотя, сам фаил RegOrganizer.exe защищён : ASProtect 2.1x SKE -> Alexey Solodovnikov [Overlay] Возможно из-за проверки этой защиты и возникает подобное недоразумение...
Делал попытки его распаковать Stripperом и отдельно ещё какой-то утилитой для снятия ASProtect, но тщетно! Где-то в середине распаковки, выдаёт ошибку, и забивает нулями, потом нормально завершает, но екзешник на выходе получается почти неработоспособным. В итоге оставил как есть, ведь работает и без снятия ASProtect...

P.S. В соответствующей ветке попросил анпакнуть RegOrganizer.exe именно той версии, что мне необходим. Если сделают, глянем, в защите было дело или нет...
Автор: coherent
Дата сообщения: 05.06.2014 19:46
Artem_Butenko
Если актуально попробуйте такой [more=скрипт]Option Explicit

Dim fso,Origin, SourcePath, MyProgPath, SandboxParent, SandboxName, SandboxPath, MyProgSourceExe, MyProgSourceIni, MyProgDestExe, MyProgDestIni, id, cmd32, cmd

Function OnLastProcessExit

Set fso = CreateObject("Scripting.FileSystemObject")

Origin = GetEnvironmentVariable("TS_ORIGIN")
SourcePath = Left(Origin, InStrRev(Origin, "\") - 1)
MyProgPath = ExpandPath("%ProgramFilesDir%\Data")
cmd32 = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & Chr(92) & SandboxName
Else
SandboxPath = SandboxParent & Chr(92) & SandboxName
End If

MyProgSourceExe = MyProgPath & "\MyProgram.exe"
MyProgSourceIni = MyProgPath & "\MyProgram.ini"
MyProgDestExe = SandboxPath & "\MyProgram.exe"
MyProgDestIni = SandboxPath & "\MyProgram.ini"

If not fso.FileExists(MyProgDestExe) then
fso.CopyFile MyProgSourceExe, MyProgDestExe
End If

If not fso.FileExists(MyProgDestIni) then
fso.CopyFile MyProgSourceIni, MyProgDestIni
End If

cmd = cmd32 & " /C" & chr(34)& MyProgDestExe & chr(34)
id = ExecuteExternalProcess(cmd)
WaitForProcess id, 0

If fso.FileExists(MyProgDestExe) Then
fso.DeleteFile(MyProgDestExe)
End if

End Function [/more]. Проверял, работает. Единственное сейчас не могу проверить с hstart.exe, потому что нет под рукой... Пока просто через cmd. Если подойдет, тогда можно будет добавить и hstart.exe.
Файлы MyProgram.exe и MyProgram.ini лежат в %ProgramFilesDir%\Data (как было изначально заявлено). При завершении копируются в песочницу, если файл MyProgram.ini уже есть, то он не перезаписывается. Файл MyProgram.exe после завершения удаляется.
Автор: SLasH
Дата сообщения: 05.06.2014 21:47
coherent
В сущности тоже самое, что и я ему писал. Но вся гадость в том, что OnLastProcessExit запускается несколько раз подряд.
AVanti473
Вот [more=скрипт]
Код: ' @appName    cmd
' @author    Ciber SLasH
' @ver        0.01
' @cDate    05.06.2014
' @mDate
'///////////////////////////////////////////////////////////////////////////////
'==[ Описание работы ]==========================================================
'///////////////////////////////////////////////////////////////////////////////
' 1. Перед запуском приложения анализируется папка
' "%UserProfile%\AppData\Local\ChemTable Software" и если она существует, то она
' бэкапится в песочницу по пути "<SnadboxPath>\_Backup"
' 2. Удаляется папка "%UserProfile%\AppData\Local\ChemTable Software"
' 3. Прописывается скрипт в автозагрузку. В раздел
' [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
' "Temp"="<путь к скрипту>"
' <путь к скрипту> = %TEMP%\<имя приложения>_afterReboot.vbs
' Далее предпологается, что приложение сделало свои дела и ОС перезагрузили.
' После перезагрузки запускается скрипт, который делает следующее:
' 1. Уадаляет папку "%UserProfile%\AppData\Local\ChemTable Software"
' 2. Восстанавливает из бэкапа то, что было в папке
' "%UserProfile%\AppData\Local\ChemTable Software" перед работой приложения
'///////////////////////////////////////////////////////////////////////////////
const DEBUG = 1

'Dim APP_NAME: APP_NAME = GetBuildOption("InventoryName")
Dim APP_NAME: APP_NAME = "cmd"
Dim SCRIPT_NAME: SCRIPT_NAME = "script.vbs"
Dim SCRIPT_EXT_NAME: SCRIPT_EXT_NAME = "ThinApp :: " & APP_NAME & " -> " & SCRIPT_NAME

Dim FSO: Set FSO = CreateObject("Scripting.filesystemObject")
const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim WORK_DIR_SUB_PATH: WORK_DIR_SUB_PATH = GetEnvironmentVariable("UserProfile") & "\AppData\Local"
Dim WORK_DIR: WORK_DIR = WORK_DIR_SUB_PATH & "\ChemTable Software"
Dim TMP_DIR: TMP_DIR = ExpandPath("%TEMP%")
' Скрипт, который будет запущен после перезагрузки
Dim SCRIPT_PATH: SCRIPT_PATH = TMP_DIR &"\"& APP_NAME &"_afterReboot.vbs"
' Внешний regedit.exe
Dim REGEDIT_EXTERNAL: REGEDIT_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\regedit.exe") & chr(34)
'-------------------------------------------------------------------------------
'--[ Выполняется при запуске ]--------------------------------------------------
'-------------------------------------------------------------------------------
Function OnFirstSandboxOwner
const FUNC_NAME = "OnFirstSandboxOwner"
' Полный путь к запущенному exe-шнику проекта.
' Пример: D:\Soft\Utils\_Portable\VMware ThinApp\Captures\cmd_1\bin\cmd.exe
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' Путь к приложению, имя приложения, путь к песочнице
Dim SourcePath, ExeName, SandboxPath
    ' LastSlash = позиция последнего backslash-а в Origin
    LastSlash = InStrRev(Origin, "\")
    ' SourcePath = путь из Origin без последнего backslash-а (путь к запущенному exe-шнику)
    SourcePath = Left(Origin, LastSlash)
    ' ExeName = имя exe-шника
    ExeName = Mid(Origin, LastSlash + 1)

    SandboxParent = GetBuildOption("SandboxPath")
    SandboxName = GetBuildOption("SandboxName")
    If SandboxParent = "." Then
        SandboxPath = SourcePath & SandboxName
    Else
        SandboxPath = SandboxParent & "\" & SandboxName
    End If

    On Error Resume Next
    Dim BACKUP_PATH: BACKUP_PATH = SandboxPath & "\_Backup"
    ' Очищаем бэкап
    If FSO.FolderExists(BACKUP_PATH) Then
        FSO.DeleteFolder(BACKUP_PATH)
    End If
    ' Бэкап "WORK_DIR" в песочницу
    If FSO.FolderExists(WORK_DIR) Then
        ' Копируем папку изнутри в песочницу
        ret = CopyFolderExternal(WORK_DIR, BACKUP_PATH)
        If ret <> 0 Then
            If DEBUG Then
                Call MsgBox( _
                    "Function: " & FUNC_NAME & vbNewLine & _
                    "SubFunction: CopyFileExternal" & vbNewLine & _
                    "SubFunction ReturnCode: " & ret & vbNewLine & _
                    "--" & vbNewLine & _
                    "Критическая ошибка, выполнение функции прервано !" _
                    , vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
                )
            End If
            Exit Function
        End If
        ' Удаление "WORK_DIR"
        FSO.DeleteFolder(WORK_DIR)
    End If

    ' Наполняем скрипт
    Set f = FSO.OpenTextFile(SCRIPT_PATH, ForWriting, true)
    f.WriteLine("Set FSO = CreateObject(""Scripting.filesystemObject"")")
    f.WriteLine("On Error Resume Next")
    ' Удаляем "WORK_DIR"
    f.WriteLine("FSO.DeleteFolder("""& WORK_DIR &""")")
    ' Восстанавливаем "WORK_DIR" из бэкапа
    f.WriteLine("FSO.CopyFolder """& BACKUP_PATH &""", """& WORK_DIR_SUB_PATH &""", true")
    ' Удаляем наш скрипт
    f.WriteLine("FSO.DeleteFile(WScript.ScriptFullName)")
    f.Close

    ' Прописываем скрипт в автозагрузку
    Dim TMP_REG: TMP_REG = TMP_DIR &"\"& APP_NAME & ".tmp"
    Set f = FSO.OpenTextFile(TMP_REG, ForWriting, true, -1)
    f.WriteLine("Windows Registry Editor Version 5.00")
    f.WriteLine
    f.WriteLine("[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]")
    SP = Replace(SCRIPT_PATH, "\", "\\")
    SP = "\"&chr(34) & SP & "\"&chr(34)
    f.WriteLine("""Temp""="""& SP & """")
    f.Close
    cmd = REGEDIT_EXTERNAL & " /S " &chr(34)& TMP_REG &chr(34)
    Call WaitForProcess(ExecuteExternalProcess(cmd), 0)
    FSO.DeleteFile(TMP_REG)

    ' Ниже можно вставить другие необходимые действия
End Function
'///////////////////////////////////////////////////////////////////////////////
'==[ Доп. функции ]=============================================================
'///////////////////////////////////////////////////////////////////////////////
'--[ Копирование папки ]--------------------------------------------------------
' @param1    - исходный путь к папке
' @param2    - путь назначения, куда будет копироваться исходная папка
' @retrun    - значение ошибки (0 - ошибок нет)
Function CopyFolderExternal(src, dst)
const FUNC_NAME = "CopyFolderExternal"
Dim dstName
    On Error Resume Next
    ' Проверка существования папки
    If Not FSO.FolderExists(src) Then
        If DEBUG Then
            Call MsgBox( _
                "Function: "&FUNC_NAME&"::FolderExists" & vbNewLine & _
                "args[0]: " & src & vbNewLine & _
                "--" & vbNewLine & _
                "Err.Number: " & Err.Number & vbNewLine & _
                "Err.Description: " & Err.Description _
                , vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
            )
        End If
        Err.Clear
        CopyFolderExternal = -1
        Exit Function
    End If

    ' Добавляем "\" в конец пути назначения, если нет backslash-а
    If Not (Right(dst, 1) = "\") Then
        dstName = dst & "\"
    End If

    ' Проверка существования папки назначения
    If Not FSO.FolderExists(dst) Then
        ' Если нет папки назначения, то создаём её
        FSO.CreateFolder(dst)
        If Err.Number <> 0 Then
            If DEBUG Then
                Call MsgBox( _
                    "Function: "&FUNC_NAME&"::CreateFolder" & vbNewLine & _
                    "args[0]: " & dst & vbNewLine & _
                    "--" & vbNewLine & _
                    "Err.Number: " & Err.Number & vbNewLine & _
                    "Err: " & Err.Description _
                    , vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
                )
            End If
            Err.Clear
            CopyFolderExternal = -2
            Exit Function
        End If
    End If

    ' Копируем исходную папку в папку назначения
    FSO.CopyFolder src, dstName, true
    If Err.Number <> 0 Then
        If DEBUG Then
            Call MsgBox( _
                "Function: "&FUNC_NAME&"::CopyFolder" & vbNewLine & _
                "args[0]: " & src & vbNewLine & _
                "args[1]: " & dstName & vbNewLine & _
                "--" & vbNewLine & _
                "Err.Number: " & Err.Number & vbNewLine & _
                "Err: " & Err.Description _
                , vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
            )
        End If
        CopyFolderExternal = -3
        Err.Clear
        Exit Function
    End If

CopyFolderExternal = 0
End Function
Автор: coherent
Дата сообщения: 05.06.2014 22:42
SLasH

Цитата:
Но вся гадость в том, что OnLastProcessExit запускается несколько раз подряд.

У меня только один раз, проверял.
Автор: SLasH
Дата сообщения: 05.06.2014 22:45
coherent

Цитата:
У меня только один раз, проверял.

Зависит от проекта. Упакуйте RollerNT и вставьте скрипт в него. OnLastProcessExit запустится 2 раза.
Автор: AVanti473
Дата сообщения: 05.06.2014 22:56
SLasH
Вы гений! Скрипт работает на 100% но вы меня похоже будете немного ругать в душе. Опять организовалась проблемка! Специфика программы предполагает также автоматическую чистку папки ТЕМП в процессе работы с программой, и соответственно файла cmd_afterReboot.vbs до использования оптимизации реестра и перезагрузки! Можно ли сделать так, чтобы этот скриптовой фаил стартовал из песочницы, вне зависимости где изначально эта песочница будет расположена? Понимаю, если я запустил портативную программу из кучи папок, то путь к песочнице в RunOnce надо как-то определить... Если это получиться, уйдёт и ещё одна совершенно незначительная для меня, но деталь - сам фаил cmd_afterReboot.vbs не останется в живой системе, как след запуска портабельного приложения!
Автор: SLasH
Дата сообщения: 05.06.2014 23:16
AVanti473
[more=скрипт]' @appName cmd
' @author Ciber SLasH
' @ver 0.01
' @cDate 05.06.2014
' @mDate
'///////////////////////////////////////////////////////////////////////////////
'==[ Описание работы ]==========================================================
'///////////////////////////////////////////////////////////////////////////////
' 1. Перед запуском приложения анализируется папка
' "%UserProfile%\AppData\Local\ChemTable Software" и если она существует, то она
' бэкапится в песочницу по пути "<SnadboxPath>\_Backup"
' 2. Удаляется папка "%UserProfile%\AppData\Local\ChemTable Software"
' 3. Прописывается скрипт в автозагрузку. В раздел
' [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
' "Temp"="<путь к скрипту>"
' <путь к скрипту> = <SnadboxPath>\<имя приложения>_afterReboot.vbs
' Далее предпологается, что приложение сделало свои дела и ОС перезагрузили.
' После перезагрузки запускается скрипт, который делает следующее:
' 1. Уадаляет папку "%UserProfile%\AppData\Local\ChemTable Software"
' 2. Восстанавливает из бэкапа то, что было в папке
' "%UserProfile%\AppData\Local\ChemTable Software" перед работой приложения
'///////////////////////////////////////////////////////////////////////////////
const DEBUG = 1

'Dim APP_NAME: APP_NAME = GetBuildOption("InventoryName")
Dim APP_NAME: APP_NAME = "cmd"
Dim SCRIPT_NAME: SCRIPT_NAME = "script.vbs"
Dim SCRIPT_EXT_NAME: SCRIPT_EXT_NAME = "ThinApp :: " & APP_NAME & " -> " & SCRIPT_NAME

Dim FSO: Set FSO = CreateObject("Scripting.filesystemObject")
const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim WORK_DIR_SUB_PATH: WORK_DIR_SUB_PATH = GetEnvironmentVariable("UserProfile") & "\AppData\Local"
Dim WORK_DIR: WORK_DIR = WORK_DIR_SUB_PATH & "\ChemTable Software"
Dim TMP_DIR: TMP_DIR = ExpandPath("%TEMP%")
' Внешний regedit.exe
Dim REGEDIT_EXTERNAL: REGEDIT_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\regedit.exe") & chr(34)
'-------------------------------------------------------------------------------
'--[ Выполняется при запуске ]--------------------------------------------------
'-------------------------------------------------------------------------------
Function OnFirstSandboxOwner
const FUNC_NAME = "OnFirstSandboxOwner"
' Полный путь к запущенному exe-шнику проекта.
' Пример: D:\Soft\Utils\_Portable\VMware ThinApp\Captures\cmd_1\bin\cmd.exe
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' Путь к приложению, имя приложения, путь к песочнице
Dim SourcePath, ExeName, SandboxPath
' LastSlash = позиция последнего backslash-а в Origin
LastSlash = InStrRev(Origin, "\")
' SourcePath = путь из Origin без последнего backslash-а (путь к запущенному exe-шнику)
SourcePath = Left(Origin, LastSlash)
' ExeName = имя exe-шника
ExeName = Mid(Origin, LastSlash + 1)

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

On Error Resume Next
' Скрипт, который будет запущен после перезагрузки
Dim SCRIPT_PATH: SCRIPT_PATH = SandboxPath &"\"& APP_NAME &"_afterReboot.vbs"
Dim BACKUP_PATH: BACKUP_PATH = SandboxPath & "\_Backup"
' Очищаем бэкап
If FSO.FolderExists(BACKUP_PATH) Then
FSO.DeleteFolder(BACKUP_PATH)
End If
' Бэкап "WORK_DIR" в песочницу
If FSO.FolderExists(WORK_DIR) Then
' Копируем папку изнутри в песочницу
ret = CopyFolderExternal(WORK_DIR, BACKUP_PATH)
If ret <> 0 Then
If DEBUG Then
Call MsgBox( _
"Function: " & FUNC_NAME & vbNewLine & _
"SubFunction: CopyFileExternal" & vbNewLine & _
"SubFunction ReturnCode: " & ret & vbNewLine & _
"--" & vbNewLine & _
"Критическая ошибка, выполнение функции прервано !" _
, vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
)
End If
Exit Function
End If
' Удаление "WORK_DIR"
FSO.DeleteFolder(WORK_DIR)
End If

' Наполняем скрипт
Set f = FSO.OpenTextFile(SCRIPT_PATH, ForWriting, true)
f.WriteLine("Set FSO = CreateObject(""Scripting.filesystemObject"")")
f.WriteLine("On Error Resume Next")
' Удаляем "WORK_DIR"
f.WriteLine("FSO.DeleteFolder("""& WORK_DIR &""")")
' Восстанавливаем "WORK_DIR" из бэкапа
f.WriteLine("FSO.CopyFolder """& BACKUP_PATH &""", """& WORK_DIR_SUB_PATH &""", true")
' Удаляем наш скрипт
f.WriteLine("FSO.DeleteFile(WScript.ScriptFullName)")
f.Close

' Прописываем скрипт в автозагрузку
Dim TMP_REG: TMP_REG = TMP_DIR &"\"& APP_NAME & ".tmp"
Set f = FSO.OpenTextFile(TMP_REG, ForWriting, true, -1)
f.WriteLine("Windows Registry Editor Version 5.00")
f.WriteLine
f.WriteLine("[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]")
SP = Replace(SCRIPT_PATH, "\", "\\")
SP = "\"&chr(34) & SP & "\"&chr(34)
f.WriteLine("""Temp""="""& SP & """")
f.Close
cmd = REGEDIT_EXTERNAL & " /S " &chr(34)& TMP_REG &chr(34)
Call WaitForProcess(ExecuteExternalProcess(cmd), 0)
FSO.DeleteFile(TMP_REG)

' Ниже можно вставить другие необходимые действия
End Function
'///////////////////////////////////////////////////////////////////////////////
'==[ Доп. функции ]=============================================================
'///////////////////////////////////////////////////////////////////////////////
'--[ Копирование папки ]--------------------------------------------------------
' @param1 - исходный путь к папке
' @param2 - путь назначения, куда будет копироваться исходная папка
' @retrun - значение ошибки (0 - ошибок нет)
Function CopyFolderExternal(src, dst)
const FUNC_NAME = "CopyFolderExternal"
Dim dstName
On Error Resume Next
' Проверка существования папки
If Not FSO.FolderExists(src) Then
If DEBUG Then
Call MsgBox( _
"Function: "&FUNC_NAME&"::FolderExists" & vbNewLine & _
"args[0]: " & src & vbNewLine & _
"--" & vbNewLine & _
"Err.Number: " & Err.Number & vbNewLine & _
"Err.Description: " & Err.Description _
, vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
)
End If
Err.Clear
CopyFolderExternal = -1
Exit Function
End If

' Добавляем "\" в конец пути назначения, если нет backslash-а
If Not (Right(dst, 1) = "\") Then
dstName = dst & "\"
End If

' Проверка существования папки назначения
If Not FSO.FolderExists(dst) Then
' Если нет папки назначения, то создаём её
FSO.CreateFolder(dst)
If Err.Number <> 0 Then
If DEBUG Then
Call MsgBox( _
"Function: "&FUNC_NAME&"::CreateFolder" & vbNewLine & _
"args[0]: " & dst & vbNewLine & _
"--" & vbNewLine & _
"Err.Number: " & Err.Number & vbNewLine & _
"Err: " & Err.Description _
, vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
)
End If
Err.Clear
CopyFolderExternal = -2
Exit Function
End If
End If

' Копируем исходную папку в папку назначения
FSO.CopyFolder src, dstName, true
If Err.Number <> 0 Then
If DEBUG Then
Call MsgBox( _
"Function: "&FUNC_NAME&"::CopyFolder" & vbNewLine & _
"args[0]: " & src & vbNewLine & _
"args[1]: " & dstName & vbNewLine & _
"--" & vbNewLine & _
"Err.Number: " & Err.Number & vbNewLine & _
"Err: " & Err.Description _
, vbOKOnly + vbCritical, "[ERROR] " & SCRIPT_EXT_NAME _
)
End If
CopyFolderExternal = -3
Err.Clear
Exit Function
End If

CopyFolderExternal = 0
End Function [/more]
Автор: AVanti473
Дата сообщения: 06.06.2014 00:07
SLasH
Вы гений, но вы меня точно убьёте! ))) Сейчас расскажу почему и только Вам решать, плюнуть на это дело и послать меня подальше, или ещё что-то возможно сделать?

Мы предполагаем перезагрузку, как нечто разумеющееся и тогда всё работает на ура - великолепно! Но, что если пользователь не воспользовался функцией оптимизации реестра и не совершил перезагрузку? Тогда вроде бы всё ок и при следующей-же перезагрузке компа всё (тоесть уже существовавшая, но забекапленная нами папка) вернётся на круги своя. А если пользователь работал с флешки и ограничился только чисткой реестра, без оптимизации? Вытащил флешку, ушёл, а после перезагрузки папке восстанавливаться неоткуда! Тоесть, сделав доброе дело, и защитив файлы бекапа и скрипт песочницей (теперь кстати автоматическая чистка до них не добирается и следов программа не оставляет, как и задумывалось), мы сделали корректную работу портабельной программы, зависимой от обязательной перезагрузки системы!

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

Боюсь, эта ситуация не решаема, ибо всегда будут какие-то непреодолимые условности.

SLasH, позвольте мне выразить Вам огромную благодарность за столь полезный для меня урок в плане скриптов! Вы даже не представляете как Вы мне помогли, несмотря на то, что общий результат похоже не будет успешным в силу обстоятельств!
Автор: SLasH
Дата сообщения: 06.06.2014 00:34
Artem_Butenko
Попробуйте такую модификацию [more=скрипта]
Код: Function OnLastProcessExit
const MegaProga = "MegaSuperProga.exe"
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Origin: Origin = GetEnvironmentVariable("TS_ORIGIN")
' В проекте папка "%drive_c%\Progs" с exe-шниками, которые нужно вынести наружу
const PROG_PATH = "C:\Program Files\Data"
' Часть пути из PROG_PATH без буквы диска: \Progs
Dim PROG_SUB_PATH: PROG_SUB_PATH = Mid(PROG_PATH, 3)
' Внешний cmd.exe
Dim CMD_EXTERNAL: CMD_EXTERNAL = chr(34) & ExpandPath("%SystemRoot%\system32\cmd.exe") & chr(34)
' В проекте "%drive_c%\Progs\hstart.exe
Dim HSTART: HSTART = PROG_PATH & "\hstart.exe"

LastSlash = InStrRev(Origin, "\")
SourcePath = Left(Origin, LastSlash)
ExeName = Mid(Origin, LastSlash + 1, Len(Origin))

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & SandboxName
Else
SandboxPath = SandboxParent & "\" & SandboxName
End If

' Внешний hstart.exe: <SandBox>\Progs\hstart.exe
Dim HSTART_EXTERNAL: HSTART_EXTERNAL = SandboxPath & "\hstart.exe"

On Error Resume Next

' Копируем файл изнутри наружу
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.ini") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.ini"" " &chr(34)& SandboxPath & "\MegaSuperProga.ini"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.ini")
End If
If Not FSO.FileExists(SandboxPath & "\hstart.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\hstart.exe"" " &chr(34)& SandboxPath & "\hstart.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\hstart.exe")
End If
If Not FSO.FileExists(SandboxPath & "\MegaSuperProga.exe") Then
cmd = CMD_EXTERNAL & " /C copy ""C:\Program Files\Data\MegaSuperProga.exe"" " &chr(34)& SandboxPath & "\MegaSuperProga.exe"
ExecuteVirtualProcess(HSTART & " /NOCONSOLE " & chr(34) & cmd & chr(34))
Do
MySleep(1)
Loop Until FSO.FileExists(SandboxPath & "\MegaSuperProga.exe")
Else
Exit Function
End If

' Запуск из песочницы
cmd = CMD_EXTERNAL & " /C " & chr(34)& SandboxPath &"\"& MegaProga & chr(34)
Call WaitForProcess(ExecuteExternalProcess(HSTART_EXTERNAL & " /NOCONSOLE " & chr(34) & cmd & chr(34)), 0)
FSO.FileDelete(SandboxPath &"\"& MegaProga)

End Function

'--[ Пауза ]--------------------------------------------------------------------
Function MySleep(interval)
Dim i,j
For i = 1 To 20000000*interval
j = 1
Next
End Function
Автор: Artem_Butenko
Дата сообщения: 06.06.2014 02:57
SLasH


Цитата:
Попробуйте такую модификацию скрипта


Не работает, проверял на Microsoft Windows 7 Ultimate (x64).

coherent


Цитата:
Artem_Butenko
Если актуально попробуйте такой скрипт. Проверял, работает. Единственное сейчас не могу проверить с hstart.exe, потому что нет под рукой... Пока просто через cmd. Если подойдет, тогда можно будет добавить и hstart.exe.  
Файлы MyProgram.exe и MyProgram.ini лежат в %ProgramFilesDir%\Data (как было изначально заявлено). При завершении копируются в песочницу, если файл MyProgram.ini уже есть, то он не перезаписывается. Файл MyProgram.exe после завершения удаляется.


Скрипт работает, только вот окно консоли хотелось бы скрыть. Последняя "хотелка" и можно будет полноценно тестировать мой плагин.

Добавлено:
Для Вас необходимый файл, -"hstart.exe".
Автор: Artem_Butenko
Дата сообщения: 06.06.2014 08:58
coherent

Так и не смог "прикрутить" hstart.exe к Вашему скрипту.
Автор: AVanti473
Дата сообщения: 06.06.2014 12:17

Цитата:
Выложите полностью ваш проект. Посмотрю что можно придумать.


Не вопрос, пожалуйста: http://rghost.ru/56205605

Позвольте лишь пару деталей:
- Пароль на архив кину в личку.
- Папка %Local AppData% в сборке присутствует, но в самом процессе сборки не участвовала, так что если сами будете пересобирать, удалите её!
- Сборка (это важно) делалась на VMware ThinApp v4.7.3-891762 (7101) Важно это потому, что собрав сперва проект на 5.0.0 Build 1391583, я обнаружил его неработоспособность, и только благодаря сторонней помощи, пришёл к выводу о его пересборке на более ранней версии ThinApp!
- Папка Captures при сборке была обозначена как "C:\1" собственно под таким названием она и лежит в архиве. Понимаю, что особого значения это не имеет, но, так, в качестве пояснения почему папка называется "1" )))
Автор: coherent
Дата сообщения: 06.06.2014 16:04
SLasH
Касательно OnLastProcessExit, здесь нельзя использовать ExecuteVirtualProcess. Это приведет к бесконечному циклу. Процес, запущенный в результате ExecuteVirtualProcess, сам становится последним. Поэтому по его завершении снова активизируется OnLastProcessExit и так по кругу.

Artem_Butenko

Цитата:
Так и не смог "прикрутить" hstart.exe к Вашему скрипту.

Попробую, но ближе к вечеру.
Автор: coherent
Дата сообщения: 07.06.2014 17:27
Artem_Butenko
Обязательно ли удалять MyProgram.exe? Насколько это принципиально? Ведь MyProgram.ini удалять не надо. Если не нужно, тогда все просто. А если нужно удалять, тогда придется добавлять проверку, завершился ли процесс MyProgram.exe.
Автор: Artem_Butenko
Дата сообщения: 07.06.2014 18:49
coherent

Да, удалять "MyProgram.exe" обязательно.
Автор: coherent
Дата сообщения: 07.06.2014 22:48
Artem_Butenko
[more=Пробуйте ]Option Explicit

Dim fso, Origin, SourcePath, MyProgSourceExe, MyProgSourceIni, hstart, hstartDest, cmd32, SandboxParent, SandboxName, SandboxPath, MyProgDestExe, MyProgDestIni, cmd, id, strComputer, strProcess

Function OnLastProcessExit

Set fso = CreateObject("Scripting.FileSystemObject")

Origin = GetEnvironmentVariable("TS_ORIGIN")
SourcePath = Left(Origin, InStrRev(Origin, "\") - 1)
MyProgSourceExe = ExpandPath("%ProgramFilesDir%\Data\MyProgram.exe")
MyProgSourceIni = ExpandPath("%ProgramFilesDir%\Data\MyProgram.ini")
hstart = ExpandPath("%ProgramFilesDir%\Data\hstart.exe")
hstartDest = SourcePath & "\hstart.exe"
cmd32 = ExpandPath("%SystemSystem%\cmd.exe")

SandboxParent = GetBuildOption("SandboxPath")
SandboxName = GetBuildOption("SandboxName")
If SandboxParent = "." Then
SandboxPath = SourcePath & Chr(92) & SandboxName
Else
SandboxPath = SandboxParent & Chr(92) & SandboxName
End If

MyProgDestExe = SandboxPath & "\MyProgram.exe"
MyProgDestIni = SandboxPath & "\MyProgram.ini"
cmd = cmd32 & " /C " & chr(34) & MyProgDestExe & chr(34)

If not fso.FileExists(MyProgDestIni) then
fso.CopyFile MyProgSourceIni, MyProgDestIni
End If

If not fso.FileExists(MyProgDestExe) then
fso.CopyFile MyProgSourceExe, MyProgDestExe
End If

If not fso.FileExists(hstartDest) then
fso.CopyFile hstart, hstartDest
End If

id = ExecuteExternalProcess(hstartDest & " /NOCONSOLE " & chr(34) & cmd & chr(34))

strComputer = "."
strProcess = "MyProgram.exe"

Do while isProcessRunning(strComputer,strProcess)
Loop

id = ExecuteExternalProcess(hstartDest & " /NOCONSOLE " & chr(34) & "taskkill /F /IM " & "Wmiprvse.exe" & chr(34))
WaitForProcess id, 0

If fso.FileExists(MyProgDestExe) Then
fso.DeleteFile(MyProgDestExe)
End if

If fso.FileExists(hstartDest) Then
fso.DeleteFile(hstartDest)
End if

End Function

Function isProcessRunning(strComputer, strProcessName)

Dim objWMIService, strWMIQuery

strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "'"
    
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

If objWMIService.ExecQuery(strWMIQuery).Count > 0 then
isProcessRunning = true
Else
isProcessRunning = false
End if

End Function[/more]
Файлы MyProgram.exe, MyProgram.ini и hstart.exe лежат в %ProgramFilesDir%\Data. По завершении MyProgram.exe и hstart.exe удаляются.

Автор: Artem_Butenko
Дата сообщения: 09.06.2014 00:02
coherent


Цитата:
Пробуйте Файлы MyProgram.exe, MyProgram.ini и hstart.exe лежат в %ProgramFilesDir%\Data. По завершении MyProgram.exe и hstart.exe удаляются.


Спасибо Вам огромное. Скрипт работает, только почему-то появляется ошибка следующего содержания:
Source: (null)
Description: (null)
File: (null)
Line 71, Character 3
at:


Такая ошибка возникает на Windows 7 x64. На Windows XP x86 скрипт работает нормально.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149

Предыдущая тема: Проблемы с закачкой


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.