PDA

View Full Version : [Q] Vấn đề Shutdow trong VBScript (WSH)



hueduongit
04-11-2002, 10:47
:question:
Trong ngôn ngữ VBScript (WSH). Thì làm cách nào để chặn quá trình Shutdow, để thực hiện một đoạn lệnh, rồi cho quá trình Shutdow tiếp tục :exclaim:

Xin cảm ơn!

Nicky
04-11-2002, 15:14
Không thể thực hiện trong VBScript đâu vì VBScript không cho phép sử dụng các API. Nếu thực hiện bằng VB thì cũng là một vấn đề khó đó.

KEM_WALL
04-11-2002, 18:05
khi shutdown thì windows sẽ gửi 1 message close đến chương trình của bạn, nếu bạn chặn event querryunload của form, xem biến unloadmode, so sánh giá trị để biết thoát ra do cái gì vd: thoát do mã chương trình, do bị end task, do win shutdown ( giá trị là gì thì quên rùi, xem trong MSDN thì biết ) nói chung bạn có thể chặn xử lý trong basic, còn vbscript thì walls kô biêt làm ;)

danceswithwolves
05-11-2002, 08:25
script được thông dịch, đâu có bẫy windows messages đâu mà nhận events ? chắc... thua quá.

hueduongit
06-11-2002, 09:48
Thank you everybody!

hueduongit
06-11-2002, 10:18
Thế các bạn giúp mình với. Thực hiện vấn đề này đối với VB6.
(mình lập trình API yếu lắm)

Xin cảm ơn!

KEM_WALL
06-11-2002, 18:06
bạn chỉ cần làm 1 chương trình bình thường, sau đó bỏ những đoạn code cần làm vào events querryunload của form, vd

private sub form_querryunload(cancel as long, unloadmode as long) ' lưu ý là walls kô nhớ rõ đối số lắm
'place code to do ..
end sub

bạn cũng có thể làm bằng events unload của form, nhưng như thế số công việc bạn làm sẽ có giới hạn hơn querryunload
bởi vì windows sẽ tự close chương trình của bạn dù nó chưa làm xong hết mọi công việc ( tuỳ theo phiên bạn win mà sau bao nhiêu giây mà kô thực hiện hết công việc thì autoclose ,vd win98 thường là 5s )
sử dụng querryunload sẽ cho bạn thêm 1 ít thời gian ( dù kô nhiều ), tốt nhất là nên place ít code thui ;)

Nicky
06-11-2002, 19:06
He..he... Cho cua nicky (http://coolcode4you.fateback.com) hình như có một bài nói về cái vụ này đó bạn có thể đến đó xem thêm.
Private Sub Form_Unload(ByVal UnloadMode As Integer)
If UnloadMode = vbAppWindows Then
' mã lệnh
End If
End Sub

White_Rose
07-11-2002, 03:13
sử dụng querryunload sẽ cho bạn thêm 1 ít thời gian ( dù kô nhiều ), tốt nhất là nên place ít code thui hình như trong queryunload thì bao lâu cũng được vì khi mình đặt cancel = true thì nó cỏn bỏ qua cả Close mà. Thông thường cái events này hay được sử dụng hơn vì nó xảy ra ngay trưóc khi Unload còn Unload chỉ xảy ra khi mọi thứ đã về cõi vĩnh hằng:)

hueduongit
07-11-2002, 11:05
Nhưng vấn đề giải quyết không triệt để, khi mà thời gian thực hiện cho đoạn chương trình của mình hơi lâu (window sẽ đóng chương trình của mình mất).
Mình muốn làm như câu hỏi lúc đâu, nhưng đối với VB6 (mình có hỏi một lần rồi, và các bạn cũng đã trả lời rồi, nhưng mình vẫn chưa làm được) :axclam:
Mong các bạn chỉ giáo tận tình. Cám ơn nhiều!

White_Rose
07-11-2002, 12:46
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
.....
End Sub

Bạn cứ để lệnh vào đây thì lâu bao nhiêu cũng được.

Nicky
07-11-2002, 17:01
Làm như WT không được vì Win sẽ tự động đóng chương trình của bạn sau một khoảng thời gian. Có thể thực hiện như sau. Nếu phát hiện Win đang shutdown thì dừng quá trình lại. Sau khi thực hiện xong công việc thì ra lệnh shutdown win.
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = vbAppWindows Then Cancel = true
' mã lệnh
End If
'Shutdown win
End Sub
Nếu bạn không biết cách shutdown thì có thể xem ở đây http://coolcode4you.fateback.com
Chúc thành công !

White_Rose
07-11-2002, 19:53
Trời đất, làm sao mà đóng được. Cái queryunload ý nghĩa của nó là sự kiện xảy ra trước khi bị unload mà.
tui thử thì thấy dù mình có lose đến bao nhiêu lần đi nữa thì cái vòng lặp chạy mất 1 phút vẫn được thực hiện đến hết. mà đó cũng không phải vòng lặp chặt vì ở trong có thực hiện DoEvents.
bản thân cái cancel = true có ý nghĩ sau khi đã thực hiện mọi lệnh trong queryunload. Nếu thực hiện xong vẫn muốn shutdown chương trình thì cứ để nó làm tự nhiên là được.
Nếu bạn vẫn cho rằng nó sẽ bị đóng thì có thể gửi một đoạn code minh hoạ lên được không? và thời gian chờ là khoảng bao nhiêu.
Mà trogn NT/2k/XP hình như bị end task trong task manager thì vô phương ngăn chặn thì phải.

Nicky
08-11-2002, 15:42
:o Khi Windows shutdown thì nó sẽ đóng chương trình của bạn cho dú bạn có muốn hay không. Nhưng VB đã giúp ta chỗ này bằng sự kiện QueryUnload, Cancel=True có nghĩa là không đóng ứng dụng nữa, tức là vẫn chạy tiếp. Bác thử đoạn code này chưa?

White_Rose
08-11-2002, 22:34
không hiểu, hic.
Tóm lại với đoạn mã sau thì đáp ứng được yêu cầu chặn quá trình Shutdow, để thực hiện một đoạn lệnh, rồi cho quá trình Shutdow tiếp tục
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
if unloadmode = vbAppWindows then 'Current Windows session ending.
'để tất cả các lệnh của bạn ở đây
end if
End Sub

LightningIII
08-11-2002, 22:56
Làm sao chặn quá trình Shutdown nổi khi đã nhấn vào nút Shutdown hả các bạn. Nếu được thì còn gọi gì là HĐH nữa.

White_Rose
09-11-2002, 02:14
Thế thì bạn nhầm rồi. Còn tuỳ đó là HĐH nào nữa.

LightningIII
09-11-2002, 23:26
Thế thì HĐH đó cũng phải xem lại rồi. Chẳng nhẽ mình viết một chương trình rồi cài lên máy rồi ngăn không cho shutdown là máy đó không thể shutsown nổi??? Khó tin quá, cho ví dụ thử coi.

Nicky
10-11-2002, 11:00
Bác không tin thật sao. Hãy sử đoạn code đơn giản sau :
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = vbAppWindows Then Cancel = True
End Sub
Biên dịch nó thành exe sau đó chạy nó. Bây giờ bác thử shutdown đi. Chắc chắn là không được...Ít nhất là không được trong Win98 vì em đã thử rồi. Có vẻ khó chấp nhận nhưng nó là thế.

White_Rose
10-11-2002, 12:27
Chỉ đúng với 9x/Me thôi. Sang NT/2k/XP là vô dụng ngay, hic.

LightningIII
10-11-2002, 21:17
Cái vụ này thì chưa thử nghen, nhưng nghe mấy vị thì chắc là có thể, he he. Xin lỗi nha. Tiểu đệ cứ tưởng...

Nicky
11-11-2002, 14:08
WinXP thì không được hả ? Thế thì tiếc thật, có cách nào chặn luôn XP không há..lol...

hueduongit
12-11-2002, 09:57
Cám ơn mọi đã chỉ giúp!
(... sau khi thử)
Theo mình nghĩ thì Nicky nói đúng đó. Còn để thực hiện một đoạn lệnh trong Form_QueryUnload, thì cần gì phải if ... then làm gì!.
Đây là mã lệnh mình nghĩ là tiện trong xử lý:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim str As String

Select Case UnloadMode
Case vbAppTaskManager
Cancel = True
str = "vbAppTaskManager"
'...
Case vbAppWindows
Cancel = True
str = "vbAppWindows"
'...
Case vbFormCode
Cancel = False
str = "vbFormCode"
'...
Case vbFormControlMenu
Cancel = True
str = "vbFormControlMenu"
'...
Case vbFormMDIForm
Cancel = True
str = "vbFormMDIForm"
'...
Case vbFormOwner
Cancel = True
str = "vbFormOwner"
'...
End Select

MsgBox "UnloadMode: " & UnloadMode, , str
End Sub

hueduongit
12-11-2002, 10:20
À, cho mình hỏi cái này luôn. Hàm API gì sẽ chặn cái shutdown được (giả sử mình khong dùng sự kiện QueryUnload nữa)
Có phải mình nhiều chuyện lắm không. Nhưng mình không biết moíư hỏi, hơn nữa mình đưa ra đây để ai quan tâm thì có thể đọc hay post lên đó mà)

Chúc mọi người dzui dze!
Thân

hueduongit
18-11-2002, 10:09
...

Nicky
18-11-2002, 14:39
Mình nghĩ là có thể nhưng cho mình thời gian nhé....để mình tìm trong MSDN thử có cách nào không đã..
C ya !

hueduongit
20-11-2002, 08:22
và mình cũng có một vấn đề nảy sinh cần hỏi đây:
Cái việc chặn Windows để thực hiện công việc của mình, xem như đã được giải quyết. Nhưng xong công việc của mình thì thực hiện gì đây bây giờ. Ý mình là truyền thông số gì cho hợp lý cho hàm ExitWindowEx. Vì Window có thể là: Shutdown, Reboot hay Logoff ... mà !

Nicky
20-11-2002, 10:38
Mình đã tìm được cách chặn quá trình shutdown bằng API dùng kĩ thuật Hook. Hôm nào mình sẽ up lên Web. Còn vấn đề bạn hỏi đúng là hơi khó...

Nicky
21-11-2002, 13:32
Here the Code :
'In Module
Public Const GWL_WNDPROC = (-4)
Public Const WM_ENDSESSION = &H16
Public Const WM_QUERYENDSESSION = &H11
Public WndProc As Long

Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Sub Hook(Lwnd As Long)
WndProc = SetWindowLong(Lwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_QUERYENDSESSION Then
WindowProc = False 'send don't shut down
Exit Function
ElseIf uMsg = WM_ENDSESSION Then
WindowProc = False
Exit Function
End If
WindowProc = CallWindowProc(WndProc, hw, uMsg, wParam, lParam)
End Function

'In Form
Private Sub Form_Load()
Hook Me.hwnd
End Sub

hueduongit
21-11-2002, 16:31
Cám ơn Nicky nhiều!

---
Khi nào có phương án cho câu hỏi của mình, thì post lên nha!!!