Avatar billede danisher Nybegynder
01. januar 2003 - 20:50 Der er 24 kommentarer og
1 løsning

Sluk computer

Hello

Jeg leder efter hjælp, til at finde ud af, hvordan jeg slukker en computer i C#...

Jeg har læst lidt på nettet, men kan ikke rigtig finde rundt i det... Der er åbenbart forskel på en lokal computer og en fjern computer...?

Kan det passe der ikke er en metode til at slukke computeren?

Håber i kan hjælpe!

På forhånd tak!

/Claus
Avatar billede rdc Nybegynder
01. januar 2003 - 20:58 #1
Hvad er C#
Avatar billede simon.ulsnes Nybegynder
01. januar 2003 - 21:03 #2
Du skal have fat i nogle DLL'er fra Windows.
Det er ikke testet, men flere ting peger på at det skal gøres sådan:

Et sted i din klasse:
[DllImport("user32.dll")] public static extern int ExitWindowsEx(uint uFlags, int dwReason);

Et andet sted i koden:
ExitWindowsEx(ShutdownFlags, 0);

ShutdownFlags kan være en af følgende:
0 - Log af
1 - Shutdown
2 - Reboot
4 - Force (don't ask)
8 - Poweroff

Jeg er ikke sikker på talværdierne - de er konstanter fra Win32 API'et, så det er ikke til at vide... Det skulle nok kunne lade sig gøre at finde på Google...

// Simon
// This sentence no verb.
Avatar billede fiskesuppe Nybegynder
01. januar 2003 - 21:04 #3
danisher -> Se om du får hjælp her:
http://p2p.wrox.com/archive/c_sharp/2002-08/85.asp

Du skal jo huske at med .net behøver du ikke lave alt i c#, forskellige dele af et program kan laves i forskellige sprog.
Avatar billede naxosnaxos Nybegynder
01. januar 2003 - 21:06 #4
Jeps du skal have fat i nogle windows API kald. Derfor skal du bruge unsafe kode mener jeg, der er vist noget pointer halløj. Men ellers er det blot at bruge simons svar. Der er dog en forskel hvis det er en NT maskine, noget med nogle previllegier der skal sættes. Men på msdn er der kodne til det, har desværre ikke lige linket pt. men ikke så svært at finde mener jeg. "Force" bruges til at tvinge en applikation til at nedlukke ;o)
Avatar billede simon.ulsnes Nybegynder
01. januar 2003 - 21:11 #5
Uddrag af winuser.h (Windows Platform SDK):
#define EWX_LOGOFF          0
#define EWX_SHUTDOWN        0x00000001
#define EWX_REBOOT          0x00000002
#define EWX_FORCE          0x00000004
#define EWX_POWEROFF        0x00000008

Jeg er næsten sikker på mit forslag virker, men jeg har desværre ikke mulighed for at afprøve det lige nu... Det er vist ikke nødvendigt at bruge unsafe kode. However, du skal have privilegier til det af systemet (det vil f.eks. ikke kunne gøres i ASP.NET).

// Simon
Avatar billede kichian Nybegynder
01. januar 2003 - 21:34 #6
simon.ulnes -> I det øjeblik man laver eksterne kald vha. Dllimport kører den del af det ihvertfald i unsafe mode.

Derudover undestøtter både VB.NET og C# api-kald med pointere, så tilgangen til windows-api'et er relativet lige til ;-)
Avatar billede simon.ulsnes Nybegynder
01. januar 2003 - 23:46 #7
kichian >> API-kald er ikke hvad der forstås ved unsafe mode i C#-sammenhæng - da har man en unsafe kodeblok som f.eks. selv skal håndtere garbage-collection og (næsten) alt det andet som .NET gør til daglig...

IntPtr er f.eks. en pointer-type til API-kald og hvor man nu måtte have brug for det. Pointers kan i øvrigt bruges i unsafe C#, hvis man har meget brug for det, hvilket man ikke har... ;)

// Simon
Avatar billede danisher Nybegynder
02. januar 2003 - 12:03 #8
Hej drenge

Tak for jeres hjælp, men kunne man eventuelt smække noget kode sammen herinde?

Tak!
Avatar billede simon.ulsnes Nybegynder
02. januar 2003 - 13:05 #9
Dette program vil slukke computeren:

using System;
using System.Runtime.InteropServices;

public class PowerOff
{
  [DllImport("user32.dll2)]
    public extern int ExitWindowsEx(uint uFlags, long dwReason);

  public PowerOff()
  {
    ExitWindowsEx(8, 0);
  }

  public static void Main(string[] args)
  {
    PowerOff app = new PowerOff();
  }
}

// Simon
Avatar billede danisher Nybegynder
02. januar 2003 - 13:39 #10
Hello

Hvorfor får jeg denne meddelelse?

PowerOff.cs(6): The DllImport attribute must be specified on a method marked 'static' and 'extern'.

Linien er:

[DllImport("user32.dll2")]

Kan i hjælpe?
Avatar billede danisher Nybegynder
02. januar 2003 - 14:06 #11
Fandt selv ud af det... :)
Avatar billede henrikbr Nybegynder
02. januar 2003 - 14:11 #12
Som man kan se neden for, er det ikke helt så enkelt som nogle af de andre foreslag... Jeg har desværre kun koden i VB, men hvis der er en C# shark der kan/vil oversætte er man meget velkommen til det :-)

Nedenstående er lavet til 4 OptionButtons, 2 CheckBoxes og en CommandButton:



Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20
Private Const TOKEN_QUERY As Long = &H8
Private Const SE_PRIVILEGE_ENABLED As Long = &H2

Private Const EWX_LOGOFF As Long = &H0
Private Const EWX_SHUTDOWN As Long = &H1
Private Const EWX_REBOOT As Long = &H2
Private Const EWX_FORCE As Long = &H4
Private Const EWX_POWEROFF As Long = &H8
Private Const EWX_FORCEIFHUNG As Long = &H10 '2000/XP only

Private Const VER_PLATFORM_WIN32_NT As Long = 2

Private Type OSVERSIONINFO
  OSVSize        As Long
  dwVerMajor      As Long
  dwVerMinor      As Long
  dwBuildNumber  As Long
  PlatformID      As Long
  szCSDVersion    As String * 128
End Type

Private Type LUID
  dwLowPart As Long
  dwHighPart As Long
End Type

Private Type LUID_AND_ATTRIBUTES
  udtLUID As LUID
  dwAttributes As Long
End Type

Private Type TOKEN_PRIVILEGES
  PrivilegeCount As Long
  laa As LUID_AND_ATTRIBUTES
End Type
     
Private Declare Function ExitWindowsEx Lib "user32" _
  (ByVal dwOptions As Long, _
  ByVal dwReserved As Long) As Long

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

Private Declare Function OpenProcessToken Lib "advapi32" _
  (ByVal ProcessHandle As Long, _
  ByVal DesiredAccess As Long, _
  TokenHandle As Long) As Long

Private Declare Function LookupPrivilegeValue Lib "advapi32" _
  Alias "LookupPrivilegeValueA" _
  (ByVal lpSystemName As String, _
  ByVal lpName As String, _
  lpLuid As LUID) As Long

Private Declare Function AdjustTokenPrivileges Lib "advapi32" _
  (ByVal TokenHandle As Long, _
  ByVal DisableAllPrivileges As Long, _
  NewState As TOKEN_PRIVILEGES, _
  ByVal BufferLength As Long, _
  PreviousState As Any, _
  ReturnLength As Long) As Long

Private Declare Function GetVersionEx Lib "kernel32" _
  Alias "GetVersionExA" _
  (lpVersionInformation As OSVERSIONINFO) As Long
 
 
 
Private Sub Command1_Click()

  Dim uflags As Long
  Dim success As Long
 
  If Option1.Value = True Then uflags = EWX_LOGOFF
  If Option2.Value = True Then uflags = EWX_SHUTDOWN
  If Option3.Value = True Then uflags = EWX_REBOOT
  If Option4.Value = True Then uflags = EWX_POWEROFF
 
  If Check1.Value = vbChecked Then uflags = uflags Or EWX_FORCE
  If Check2.Value = vbChecked Then uflags = uflags Or EWX_FORCEIFHUNG
 
  'assume success
  success = True
 
  'if running under NT or better,
  'the shutdown privledges need to
  'be adjusted to allow the ExitWindowsEx
  'call. If the adjust call fails on a NT+
  'system, success holds False, preventing shutdown.
  If IsWinNTPlus Then
      success = EnableShutdownPrivledges()
  End If

  If success Then Call ExitWindowsEx(uflags, 0&)

End Sub
 

Private Function IsWinNTPlus() As Boolean

  'returns True if running Windows NT,
  'Windows 2000, Windows XP, or .net server
  #If Win32 Then
 
      Dim OSV As OSVERSIONINFO
 
      OSV.OSVSize = Len(OSV)
 
      If GetVersionEx(OSV) = 1 Then

        IsWinNTPlus = (OSV.PlatformID = VER_PLATFORM_WIN32_NT) And _
                      (OSV.dwVerMajor >= 4)
      End If

  #End If

End Function


Private Function EnableShutdownPrivledges() As Boolean

  Dim hProcessHandle As Long
  Dim hTokenHandle As Long
  Dim lpv_la As LUID
  Dim token As TOKEN_PRIVILEGES
 
  hProcessHandle = GetCurrentProcess()
 
  If hProcessHandle <> 0 Then
 
    'open the access token associated
    'with the current process. hTokenHandle
    'returns a handle identifying the
    'newly-opened access token
      If OpenProcessToken(hProcessHandle, _
                        (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), _
                        hTokenHandle) <> 0 Then
 
        'obtain the locally unique identifier
        '(LUID) used on the specified system
        'to locally represent the specified
        'privilege name. Passing vbNullString
        'causes the api to attempt to find
        'the privilege name on the local system.
        If LookupPrivilegeValue(vbNullString, _
                                "SeShutdownPrivilege", _
                                lpv_la) <> 0 Then
       
          'TOKEN_PRIVILEGES contains info about
          'a set of privileges for an access token.
          'Prepare the TOKEN_PRIVILEGES structure
          'by enabling one privilege.
            With token
              .PrivilegeCount = 1
              .laa.udtLUID = lpv_la
              .laa.dwAttributes = SE_PRIVILEGE_ENABLED
            End With
 
          'Enable the shutdown privilege in
          'the access token of this process.
          'hTokenHandle: access token containing the
          '  privileges to be modified
          'DisableAllPrivileges: if True the function
          '  disables all privileges and ignores the
          '  NewState parameter. If FALSE, the
          '  function modifies privileges based on
          '  the information pointed to by NewState.
          'token:  TOKEN_PRIVILEGES structure specifying
          '  an array of privileges and their attributes.
          '
          'Since were just adjusting to shut down,
          'BufferLength, PreviousState and ReturnLength
          'can be passed as null.
            If AdjustTokenPrivileges(hTokenHandle, _
                                    False, _
                                    token, _
                                    ByVal 0&, _
                                    ByVal 0&, _
                                    ByVal 0&) <> 0 Then
                                   
              'success, so return True
              EnableShutdownPrivledges = True
 
            End If  'AdjustTokenPrivileges
        End If  'LookupPrivilegeValue
      End If  'OpenProcessToken
  End If  'hProcessHandle

End Function
Avatar billede danisher Nybegynder
02. januar 2003 - 15:11 #13
Hvad gør jeg forkert?

PowerOff.cs:
using System;
using System.Runtime.InteropServices;

public class PowerOff
{
    [DllImport("user32.dll2")]
    public static extern int ExitWindowsEx(uint uFlags, long dwReason);

    public PowerOff()
    {
        ExitWindowsEx(8, 0);
    }
}

Mit program:
PowerOff app = new PowerOff();

Håber i kan hjælpe!
Avatar billede burningice Nybegynder
02. januar 2003 - 15:33 #14
hvilken fejl får du?
Avatar billede henrikbr Nybegynder
02. januar 2003 - 15:53 #15
>> [DllImport("user32.dll2")]

Der skal vel ikke være et 2-tal efter .dll
Avatar billede simon.ulsnes Nybegynder
02. januar 2003 - 17:23 #16
nej, det var en typo...
Avatar billede danisher Nybegynder
03. januar 2003 - 15:37 #17
Okay, nu har jeg lavet det lidt om...

PowerOff.cs:
using System;
using System.Runtime.InteropServices;

public class PowerOff
{
    [DllImport("user32.dll")]
    public static extern int ExitWindowsEx(uint uFlags, long dwReason);

    public void Sluk()
    {
        //System.Windows.Forms.MessageBox.Show("Test");
        ExitWindowsEx(8, 0);
    }
}

I mit program:
PowerOff Computer = new PowerOff();

og når der så skal slukkes:
Computer.Sluk();

Men der kommer ikke nogen fejlmeddelser eller noget... Det virker ikke... :(

Er der nogen der kan hjælpe...?

På forhånd tak!

Mvh

Claus
Avatar billede simon.ulsnes Nybegynder
03. januar 2003 - 16:07 #18
Jeg tror talkonstanterne er anderledes i Windows 2000/XP - for eksempel gjorde 4 at min computer loggede ud, men ikke slukkede.

Desuden står der på MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/exitwindowsex.asp) at den sidste parameter (dwReason) ikke må være nul, da nedlukningen da vil blive forsinket. Prøv med 1 eller -1.

Ud over det synes jeg ikke det er retfærdigt at naxosnaxos skal have alle point, da jeg mener jeg har givet et langt mere brugbart svar (som rent faktisk virker med de rigtige indstillinger)!

// Simon
Avatar billede henrikbr Nybegynder
03. januar 2003 - 16:35 #20
simon.ulsnes: ved at angive 4 (hex) som dwOptions fortæller du ExitWindowsEx at det er en Forced logoff. Forced=4 + Logoff=0. Så den er god nok.
Avatar billede henrikbr Nybegynder
03. januar 2003 - 16:49 #21
Hvis man vil have en tvungen Poweroff af PC'en angives 28 i dwOptions parametren. Her lukker windows helt ned uden at vente på ret lang tid på kørende programmer, services og lignende. Desuden beder windows strømforsyningen om at slukke.
Avatar billede henrikbr Nybegynder
03. januar 2003 - 17:07 #22
For dem der ikke lige ved det: uFlags=dwOptions
(bare lige en tanke :-)
Avatar billede danisher Nybegynder
03. januar 2003 - 21:25 #23
Det er også noget galt.... Jeg ramte forkert... Er der nogen måde at gøre det om, sådan at det ikke er godkendt spørgsmål mere???
Avatar billede danisher Nybegynder
03. januar 2003 - 21:32 #24
Jeg har prøvet at sende en mail til info@eksperten.dk, men de svarer ikke rigtigt...
Avatar billede simon.ulsnes Nybegynder
03. januar 2003 - 22:39 #25
Du kan jo snakke med naxosnaxos eller noget, jeg er sikker på at han er modtagelig over for fornuft... Ellers betyder det altså heller ikke alt med de pokkers point.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester