PureBasic - форум

»нформаци€ о пользователе

ѕривет, √ость! ¬ойдите или зарегистрируйтесь.


¬ы здесь » PureBasic - форум » ¬опросы по PureBasic » удалить родительскую директорию (вместе с файлом).


удалить родительскую директорию (вместе с файлом).

—ообщений 1 страница 30 из 32

1

„то-то у мен€ не получаетс€ ((
вообщем, есть директори€. находитс€ она в стандартной "C:\Program Files (x86)\PSE" , где "PSE" это уже мо€ директори€
в ней лежит единственный файл с именем, пусть 004.exe
как, запустив этот файл добитьс€ ликвидации и его самого и его родительской директории PSE. ¬ идеале, было бы здорово  еще на прощанье выполгнить что-то типа MessageRequester("","ѕока!") ?
ћаксимум, что € добилс€, это удалени€ самого файла

 од:
ShellExecute_(0, "RunAS", GetEnvironmentVariable("comspec"), "/c del "+Chr(34)+ProgramFilename()+Chr(34), "", #SW_SHOWNORMAL)

ну, еще. не пробовал создани€ батника в темп директории, его запуск. с попыткой убить директорию с файлом. Ќо и там, чувствую, засады будут в виде защитника виндов или еще что-то пдобного.
≈сть какое-нибудь простое решение?

ќтредактировано Goga (11.09.2021 13:12:37)

0

2

ј от админа удал€етс€?
» почему бы не DeleteDirectory?

ќтредактировано AZJIO (11.09.2021 13:37:25)

0

3

админом тоже не удал€етс€. ѕопробовал DeleteDirectory не может удалить ни сам файл, ни саму директорию.

0

4

вот теперь пон€л, удалить файл работающей программы. Ќадо сделать перебор процессов запрашива€ путь исполн€емого файла, убить процесс, а потом удалить файл.

Ќадо на оффоруме погуглить GetModuleFileNameEx

 од:
EnableExplicit
     	
; ¬озвращает путь к EXE-файлу запущенного процесса зна€ его дескриптор окна или PID
Procedure.s ProcessNameFromHwnd(hWnd)
	Protected PID, psapi_dll, Path$, GetModuleFileNameEx, hProcess
	psapi_dll = OpenLibrary(#PB_Any, "psapi.dll")
	If psapi_dll
    GetModuleFileNameEx = GetFunction(psapi_dll, "GetModuleFileNameExW") ; “олько имена путей в ёникоде!
    If GetModuleFileNameEx
    	If GetWindowThreadProcessId_(hWnd, @PID)
        hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #Null, PID)
        If hProcess
        	Path$ = Space(#MAX_PATH)
        	If Not CallFunctionFast(GetModuleFileNameEx, hProcess, #Null, @Path$, #MAX_PATH)
            Path$ = ""
        	EndIf
        	CloseHandle_(hProcess)
        EndIf
    	EndIf
    EndIf
    CloseLibrary(psapi_dll)
	EndIf
	ProcedureReturn Path$
EndProcedure

Define hWnd, Path$

hWnd=FindWindow_(0, "«аголовок окна")
If hWnd
	Path$=ProcessNameFromHwnd(hWnd)
	Debug Path$
EndIf

» ещЄ вариант - удалить в корзину. “о есть процесс позвол€ет переименовать файл или переместить его, а после перезагрузки уже не сможет его найти, но в текущей сессии он всЄ ещЄ будет исполн€тс€.

я в Linux, поэтому даже при желании пока нет возможности быстро переделать.

ќтредактировано AZJIO (06.10.2021 15:56:57)

0

5

про удаление папки есть в справке, там расписаны варианты удалени€ папки с файлами
не всЄ так просто с удалением папки

0

6

newJS написал(а):

про удаление папки есть в справке, там расписаны варианты удалени€ папки с файлами
не всЄ так просто с удалением папки

придумал €, казалось бы, надежный путь. «апускаю программу, записываю в темп директории exe-шник, запускаю его, а родительскую программу закрываю. Ётот exe-шник удал€ет директорию , потом удал€ет сам себ€  c помощью встроенного cmd.exe
» это все прекрасно работает... с отключенным защитником виндов. ≈сли этот защитник оставить, то он уже на этапе записи файл.exe в темп директорию душит все и вс€.

ќтредактировано Goga (18.09.2021 05:00:42)

0

7

Goga
ј если вернутс€ к первоначальному варианту (без временной папки), но через cmd выполн€ть ещЄ и taskkill программы?

0

8

Goga
ћожет через планировщик можно как-то выкрутитьс€?

0

9

Smitis написал(а):

Goga
ј если вернутс€ к первоначальному варианту (без временной папки), но через cmd выполн€ть ещЄ и taskkill программы?

можно попробовать, хот€ не уверен. ” мен€ есть вариант, когда все отлично работает, реализованный через  wscript.exe. Ќо все отлично работает, только если программа не сидит на виндовом диске —. ¬от на диске D- это, пожалуйста, все удал€етс€ замечательно. я никогда особо не обращал внимани€ на приписку мелком€гких "проверенный издатель". ” мен€-то статус "никто и звать никак", мо€ прога на диске — спотыкаетс€ через раз, пока ее под админом не запустишь, а "проверенных издателей" все чики пуки работает. ѕроверил все права на доступ одинаковы. Ќаверное, в этом дело, надо изучить подробнее этот момент.

0

10

Goga
ƒиск C: системный, а в папках уже не требуетс€ админа. » зачем на диске —: если можно в %temp%?

0

11

вообщем, нашел €. наконец-то,  у себ€ когда-то кем-то подаренный мне код удалени€ родительсткой папки. ¬се отлично, но есть одна досада, не справл€етс€ скрипт с папкой содержащей пробелы в названии. “.е. даже если на пути к папке. подлежащей удалению попадаетс€ папка с пробелом (например, всеми нами любима€ c:\Program Files (x86)) скрипт не срабатывает. “.к. € не спец ни разу в Vbscript, может, кто поможет подправить код, чтобы все заработало:

 од:
; Ќ≈ «јѕ”— ј… ѕ–ќ√” в своей ƒ»–≈ “ќ–»»!!!!!!!!! ”ƒјЋ»Ў№ ¬—≈ ƒјЌЌџ≈!!!!!!!!!!!!!!!!!!
NameProga$=ProgramFilename() 
  DirToDelete.s = GetPathPart(NameProga$)  
  DirToDelete = LCase(Left(DirToDelete, Len(DirToDelete)-1))  
  TempDir.s = GetTemporaryDirectory() 
  ScriptName.s = TempDir + "3.vbs"  
  
  If CreateFile(0, ScriptName)
       WriteData(0,?vbs_begin, ?vbs_end-?vbs_begin)
  CloseFile(0) 
       parametr$="//nologo"+" "+ScriptName+" "+DirToDelete
       Result =MessageRequester("","“ы точно запускаешь это в тестовой папке?", #PB_MessageRequester_YesNo):If Result = #PB_MessageRequester_No:End:EndIf ;страховка 
       ShellExecute_(0, "RunAS", "wscript.exe", parametr$, TempDir, #SW_SHOWNORMAL) 
  EndIf
  
     
  VBS_BEGIN:
     IncludeBinary "3.vbs"
  VBS_END:

этот скрипт положить в туже директорию, что и компилируемый файл, обозвать 3.vbs

 од:
If Wscript.Arguments.Count=1 Then
  Dim x
  Wscript.Sleep 1000
  Path = Wscript.Arguments(0)
  Set objShell = CreateObject("Wscript.Shell")
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  If objFSO.FolderExists(Path) Then
    'CurrentPath = objFSO.GetAbsolutePathName(".")
    'msgbox CurrentPath
    On Error Resume Next
    For x = 1 To 10
      objFSO.DeleteFolder(Path)
      If Err.Number = 0 Then Exit For
      Wscript.Sleep 1000
    Next
  End If
  Call objFSO.DeleteFile(WScript.ScriptFullName, True)
End If

0

12

 од:
DirToDelete = #DOUBLEQUOTE$ + LCase(Left(DirToDelete, Len(DirToDelete)-1)) + #DOUBLEQUOTE$

ќтредактировано Lin (06.10.2021 09:49:27)

0

13

”даление при помощи батника, который создаЄтс€ динамически:

 од:
; Ќе запускать файл на исполнение! Ѕудет удалено всЄ, что есть в этой папке вместе с папкой!
Select MessageRequester("¬нимание! ", "”далить программу и еЄ каталог?", #MB_YESNO|#MB_ICONWARNING)
  Case #IDYES
    PathPart$ = GetPathPart(ProgramFilename())
    If CreateFile(0, "del.bat")
       WriteStringN(0,"@echo off") 
       WriteStringN(0,"CD\.")
       WriteStringN(0,"timeout /t 2 /nobreak >nul 2>nul")
       WriteStringN(0,"rd /s /q " + Chr(34) + PathPart$  + Chr(34) )
      CloseFile(0)
    RunProgram("del.bat")
    End
    EndIf
  Case #IDNO
    MessageRequester("¬нимание! ", "ќтменено пользователем")
EndSelect

0

14

¬от так у мен€ чистка папки temp.

 од:
cd /d "%temp%" && rd /s /q "."

но ещЄ что важно и почему € не люблю батники, если %temp% не определена, или в другом скрипте например папка не существует, то скрипт примет за текущий тот, в котором находитс€ и может тупо очистить ваш жЄсткий диск. “ак что с такими вещами неопределЄнными надо всЄ продумать.

0

15

¬иниѕур написал(а):

Chr(34)

чЄт всЄ врем€ забываю про #DOUBLEQUOTE$

ќтредактировано Lin (06.10.2021 09:52:57)

0

16

Lin написал(а):

чЄт всЄ врем€ забываю про #DOUBLEQUOTE$

Ѕуковок много. “ак короче и нагл€днее.

 од:
~"\""

0

17

ѕЄтр
тоже на тильду перешЄл, но вот выкладывал код дл€ чистки комментариев, который провер€ет пары кавычек, у него проблемы с такими строками, надо добавл€ть мессагу о наличии таких строк и дополнительную проверку отсутстви€ их обрезки. — Chr(34) такой проблемы нет.

ќтредактировано AZJIO (06.10.2021 12:28:29)

0

18

Lin написал(а):

#DOUBLEQUOTE$

” мен€ на автомате Chr(34) за 30 лет с Ѕейсиком. “ам ещЄ как то "/" и "\" тоже свою константу имеет. Ќо € такие глупости даже запоминать не хочу.

0

19

¬иниѕур

"/" и "\"

#PS$ уже запомнил, в реальности редко используетс€, так как пр€мые пути - редка€ необходимость. ѕри компил€ции несколькими иконками кладу отдельно в папку images и уже в Data надо images + #PS$ + pic1.png, и второй случай, когда путь в папке конфигов, если там разветвлЄнна€ система, а не просто €вный путь. Ёто проще чем использовать CompilerSelect #PB_Compiler_OS

ќбновил выше код - получение пути EXE-файла от дескриптора окна\процесса.

ќтредактировано AZJIO (06.10.2021 16:00:21)

0

20

AZJIO написал(а):

Ёто проще чем использовать CompilerSelect #PB_Compiler_OS

ј смысл, если ¬инде пофигу в какую сторону слеш смотрит, она съест и так и так, а дл€ остальных можно смело писать "images/pic1.png", это гораздо короче, чем images + #PS$ + pic1.png

0

21

AZJIO написал(а):

GetModuleFileNameEx = GetFunction(psapi_dll, "GetModuleFileNameExW") ; “олько имена путей в ёникоде

если нужен только свой путь:

 од:
EXE_Location$ = Space(#MAX_PATH)
GetModuleFileName_(#Null, EXE_Location$, #MAX_PATH)
Debug EXE_Location$
ѕЄтр написал(а):

Ѕуковок много.

тут согласен, поэтому и забываю :) но константой удобно что подсвечиваетс€... у ‘реда в коде IDE € такой костыль находил: #Q$ = Chr(34)

ќтредактировано Lin (06.10.2021 17:56:39)

0

22

Lin написал(а):

если нужен только свой путь:

ProgramFilename()

 стати код € вз€л тут, сначала из AutoIt3 на половину переделал, потом подумал, а что € мучаюсь, € же находил готовую, только проверю что она соответствует, а она даже лучше оказалась, в плане AutoIt3-варианту надо PID указывать, то есть отдельно функци€ PID  из hWnd, а в PureBasic сразу из hWnd, ура в копилку ещЄ одна, у мен€ несколько функций которым € ищу аналоги по мере изучени€, чтобы переписать все свои программы, а данной функцией € при работе со сторонним окном провер€ю что оно принадлежит например эксплореру, когда заголовок может быть любой, и класс может совпасть, а путь никогда.

0

23

Lin написал(а):

 од:

DirToDelete = #DOUBLEQUOTE$ + LCase(Left(DirToDelete, Len(DirToDelete)-1)) + #DOUBLEQUOTE$

спасибо

¬иниѕур написал(а):

”даление при помощи батника, который создаЄтс€ динамически:
 од:

; Ќе запускать файл на исполнение! Ѕудет удалено всЄ, что есть в этой папке вместе с папкой!
Select MessageRequester("¬нимание! ", "”далить программу и еЄ каталог?", #MB_YESNO|#MB_ICONWARNING)
  Case #IDYES
    PathPart$ = GetPathPart(ProgramFilename())
    If CreateFile(0, "del.bat")
       WriteStringN(0,"@echo off")
       WriteStringN(0,"CD\.")
       WriteStringN(0,"timeout /t 2 /nobreak >nul 2>nul")
       WriteStringN(0,"rd /s /q " + Chr(34) + PathPart$  + Chr(34) )
      CloseFile(0)
    RunProgram("del.bat")
    End
    EndIf
  Case #IDNO
    MessageRequester("¬нимание! ", "ќтменено пользователем")
EndSelect

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

0

24

»ли € чего-то не понимаю или одно из двух, создаЄтс€ батник в кодировке UTF и ¬инда (’–-64) не видит путь дл€ удалени€, пересохран€ю батник в 866 и всЄ нормально отрабатывает.  ак ѕурик заставить сразу в 866 сохранить?

0

25

Rerer777 написал(а):

 ак ѕурик заставить сразу в 866 сохранить?

https://www.purebasic.com/documentation … efile.html
https://www.purebasic.com/documentation … ormat.html

0

26

Rerer777 написал(а):

»ли € чего-то не понимаю или одно из двух, создаЄтс€ батник в кодировке UTF и ¬инда (’–-64) не видит путь дл€ удалени€

Ѕатник должен быть без BOM.
¬ начале батника должна сто€ть команда chcp 65001.

0

27

ѕопробовал конвертировать в 866 и обратно

 од:
EnableExplicit

Procedure StrToArrLetter(Array Arr.s{1}(1), String$)
	Protected LenStr, i
	LenStr = Len(String$)
	If LenStr
    ReDim Arr(LenStr - 1)
    PokeS(Arr(), String$, -1, #PB_String_NoZero)
	EndIf
	ProcedureReturn
EndProcedure

Procedure.s Encode1251To866(sString$)
	Protected sResult$ = "", i, code
	Protected cp1251$, cp866$, Pos
	Protected Dim Arr866.s{1}(0)
	Protected Dim ArrSource.s{1}(0)
	
	cp1251$ = "абвгдеЄжзийклмнопрстуфхцчшщъыьэю€јЅ¬√ƒ≈®∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёя"
	cp866$ = "†°Ґ£§•с¶І®©™Ђђ≠ЃѓабвгдежзийклмнопАБВГДЕрЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
	StrToArrLetter(Arr866(), cp866$)
	StrToArrLetter(ArrSource(), sString$)
	
	For i = 0 To ArraySize(ArrSource())
    code = Asc(ArrSource(i))
    If code >= 1025 And code <= 1105
    	Pos = FindString(cp1251$, ArrSource(i))
    	If Pos
        ArrSource(i) = Arr866(Pos - 1) 
    	EndIf
    EndIf
	Next
	
	ProcedureReturn PeekS(ArrSource())
EndProcedure

Procedure.s Encode866To1251(sString$)
	Protected sResult$ = "", i, code
	Protected cp1251$, cp866$, Pos
	Protected Dim Arr866.s{1}(0)
	Protected Dim ArrSource.s{1}(0)
	
	cp866$ = "абвгдеЄжзийклмнопрстуфхцчшщъыьэю€јЅ¬√ƒ≈®∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёя"
	cp1251$ = "†°Ґ£§•с¶І®©™Ђђ≠ЃѓабвгдежзийклмнопАБВГДЕрЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
	StrToArrLetter(Arr866(), cp866$)
	StrToArrLetter(ArrSource(), sString$)
	
	For i = 0 To ArraySize(ArrSource())
    code = Asc(ArrSource(i))
    If code >= 152 And code <= 8482
    	Pos = FindString(cp1251$, ArrSource(i))
    	If Pos
        ArrSource(i) = Arr866(Pos - 1) 
    	EndIf
    EndIf
	Next
	
	ProcedureReturn PeekS(ArrSource())
EndProcedure

Define Str1.s, Str2.s

Str1 = Encode1251To866("ѕривет")
Str2 = Encode1251To866("абв-ю€--јЅ¬-ёя")
Debug Str1
Debug Str2
Str1 = Encode866To1251(Str1)
Str2 = Encode866To1251(Str2)
Debug Str1
Debug Str2

перед этим пробовал переделать функцию из AutoIt3, но она работает только с ANSI, такую строку € просто не могу получить, только бинарное в пам€ти, но не как переменную. “о есть даже если работать с цифрами, то Asc() возвращает тоже юникодный вариант. ’от€ наверно можно попробовать работать с байтами.

 од:
Procedure.s _Encoding_1251To866(sString$)
	Protected sResult$ = "", iCode, i
	Protected Dim Arr866.s{1}(0)
	
	StrToArrLetter(Arr866(), sString$)

	For i = 0 To ArraySize(Arr866())
    iCode = Asc(Arr866(i))

    Select iCode
    	Case 192 To 239
        Arr866(i) = Chr(iCode - 64)
    	Case 240 To 255
        Arr866(i) = Chr(iCode - 16)
    	Case 168
        Arr866(i) = Chr(240)
    	Case 184
        Arr866(i) = Chr(241)
    	Case 185
        Arr866(i) = Chr(252)
    EndSelect

    sResult$ + Arr866(i)
	Next

	ProcedureReturn sResult$
EndProcedure

”лучшение: так как буквы по пор€дку, то вместо поиска позиции используетс€ вычитание числа.

 од:
Procedure.s Encode1251To866(sString$)
	Protected sResult$ = "", i, code
	Protected cp1251$, cp866$
	Protected Dim Arr866.s{1}(0)
	Protected Dim ArrSource.s{1}(0)
	
	cp1251$ = "јЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю€"
	cp866$ = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓабвгдежзийклмноп"
	StrToArrLetter(Arr866(), cp866$)
	StrToArrLetter(ArrSource(), sString$)
	
	For i = 0 To ArraySize(ArrSource())
    code = Asc(ArrSource(i))
    Select code
    	Case 1040 To 1103
        ArrSource(i) = Arr866(code - 1040) 
    	Case 1025
        ArrSource(i) = "р"
    	Case 1105
        ArrSource(i) = "с"
    EndSelect
	Next
	
	ProcedureReturn PeekS(ArrSource())
EndProcedure

ЌашЄл такую у себ€ же в ChkDskGui

 од:
Import "user32.lib"
	OemToCharBuffA(*Buff,*Buff1,SizeBuff)
	CharToOemBuffA(*Buff,*Buff1,SizeBuff)
EndImport

Procedure.s ToOem(String$)
	Protected Ret$="", *Buff, SizeBuff=Len(String$)
	If SizeBuff>0
    *Buff=AllocateMemory(SizeBuff+1)
    PokeS(*Buff, String$, SizeBuff, #PB_Ascii)
    CharToOemBuffA(*Buff, *Buff, SizeBuff)
    Ret$=PeekS(*Buff, SizeBuff, #PB_Ascii)
    FreeMemory(*Buff)
	EndIf
	ProcedureReturn Ret$
EndProcedure

ќтредактировано AZJIO (10.10.2021 08:07:58)

0

28

ѕол дела готово. Ѕатник создаЄтс€ и работает, вот только работает он если запустить его ручками, а запущенный из программы он выкидывает ошибку что chcp не €вл€етс€ командой или файлом.  ак будто интерпретатор разный.  ак буду перезагружать комп попробую из 32 битной системы запустить всЄ это безобразие, может сработает, тогда и буду дальше копать.

вопрос не по теме

» раз уж здесь, наткнулс€ на такую фишку. — интернета скачал скрипты и в углу где стрелка у €рлыков что-то в виде часов белых на чЄрном квадрате, может кто подскажет что это за обозначение?

0

29

Rerer777 написал(а):

а запущенный из программы он выкидывает ошибку что chcp не €вл€етс€ командой или файлом

chcp внешн€€ команда. ћожет с переменными среды PATH/PATHEXT проблема. »ли с разр€дностью. »ли ещЄ что.
¬ы батник из программы как запускаете? „ерез cmd или напр€мую?

ќтредактировано Smitis (11.10.2021 22:33:12)

0

30

Rerer777
ƒл€ эксперимента можно ещЄ в CreateFile указать #PB_Ascii и CHCP 1251

ќтличие запуска ручками и из программы это "текуща€ директори€", то есть файл будет воспринимать каталог запускающей программы как текуща€ директори€. ≈сли в bat-файле есть ещЄ что-то св€занное с текущей директорией, то может вызвать проблему. ћожно вставить пример из ExamineEnvironmentVariables(), чтобы посмотреть содержимое окружени€.

ќтредактировано AZJIO (11.10.2021 18:31:17)

0


¬ы здесь » PureBasic - форум » ¬опросы по PureBasic » удалить родительскую директорию (вместе с файлом).