Avatar billede george Nybegynder
22. februar 2003 - 12:47 Der er 112 kommentarer og
2 løsninger

Program til at lukke Win98

Jeg har brug for sourcekode til et lille program som kan "føle" om et program kører. Gør det ikke det skal Windows lukke ned.

Jeg har den kode der undersøger om et program kører, men mangler resten. Programmet skal kører i baggrunden og skal løbendede checke om programmet er lukket ned. Det skal virke på en Win98 platform.

Er der nogen der kan og vil lave det?

Kan desværre kun give max 200 point her så der er 300 mere til den der løser opgaven og 500 mere hvis opgaven er løst inden mandag morgen. Det haster meget og jeg skal bruge koden hurtigst muligt.

Her er koden :

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintProcessNameAndID( DWORD processID )
{
    char szProcessName[MAX_PATH] = "unknown";

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                  PROCESS_VM_READ,
                                  FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
            &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                              sizeof(szProcessName) );
        }
        else return;
    }
    else return;

    // Print the process name and identifier.

    printf( "%s (Process ID: %u)\n", szProcessName, processID );

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintProcessNameAndID( aProcesses[i] );
}
Avatar billede arne_v Ekspert
22. februar 2003 - 13:59 #1
Du må ikke give mere end 200 point for et spørgsmål.
Avatar billede arne_v Ekspert
22. februar 2003 - 14:01 #2
Med hensyn til, hvordan du lukker din Windows ned, så
er der noget kode på:
  http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=503
Avatar billede george Nybegynder
22. februar 2003 - 14:21 #3
Nå men så må I jo nøjes med 200 point.

Jeg er ikke i stand til at kode det i C++ endnu, så grundet tidspresset beder jeg nu om hjælp her.
Avatar billede george Nybegynder
22. februar 2003 - 14:23 #4
Kigger lige på linket alligevel, der er jo før sket mirakler ;-)
Avatar billede george Nybegynder
22. februar 2003 - 16:06 #5
Jeg har kigget lidt på koden, men er ikke i stand til at strikke noget kode sammen på så kort tid.

Håber der er nogen der har mod på at lave koden for mig. Jeg prøver dog selv at se om jeg kan finde ud af det, men har ikke de store forhåbninger da jeg ikke er en C++ haj.
Avatar billede arne_v Ekspert
22. februar 2003 - 16:14 #6
Strikke noget kode sammen ?

1 linie:

ExitWindowsEx( EWX_SHUTDOWN, 0 );

og så skulle Windows 98 gerne lukke !
Avatar billede arne_v Ekspert
22. februar 2003 - 16:15 #7
Du skal så lige have et test udenom så den kun lukker, hvis et bestemt program
ikke kører, men det forstpd jeg på dit spørgsmål, at du havde styr på.
Avatar billede george Nybegynder
22. februar 2003 - 17:33 #8
Nej det er kun kode til at vise de programmer der kører.

Jeg skal jo bruge noget kode med en løkke der kan opfange når programmet afsluttes og herefter skal koden du skriver sættes ind.

Jeg ved ikke hvor i koden jeg skal placerer en if sætning og hvordan den skal "skrues" sammen for at opfange når programmet lukkes ned.
Avatar billede arne_v Ekspert
22. februar 2003 - 17:54 #9
Jeg har prøvet at modificere din kode lidt:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "psapi.h"

int PrintProcessNameAndID( DWORD processID )
{
    char szProcessName[MAX_PATH] = "unknown";

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                  PROCESS_VM_READ,
                                  FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
            &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                              sizeof(szProcessName) );
        }
        else return 0;
    }
    else return 0;

    // Print the process name and identifier.

    printf( "%s (Process ID: %u)\n", szProcessName, processID );

    CloseHandle( hProcess );
   
    return (strcmp(szProcessName, "xxxxx.exe")==0);
}

int  main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;
    int fnd;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return 1;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.
    fnd = 0;
    for ( i = 0; i < cProcesses; i++ )
        fnd = fnd || PrintProcessNameAndID( aProcesses[i] );
   
    if(!fnd) printf("shutdown\n");
}
Avatar billede arne_v Ekspert
22. februar 2003 - 17:55 #10
Det er absolut ikke køn kode, men fnd angiver hvorvidt xxxxx.exe kører, så
hvis du:
  - erstatter den printf med shutdown kaldet
  - erstattet xxxxx.exe med den rigtige exe
så burde det faktisk virke.

Koden kunne struktures betydeligt bedre, men det må være en anden gang.
Avatar billede george Nybegynder
22. februar 2003 - 18:11 #11
Jeg får en fejl når jeg compiler :
c:\program files\microsoft visual studio\jk\test21\test21.cpp(68) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Error executing cl.exe.

test21.obj - 1 error(s), 0 warning(s)


Er dette sat rigtig ind i koden ?

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "psapi.h"

int PrintProcessNameAndID( DWORD processID )
{
    char szProcessName[MAX_PATH] = "unknown";

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                  PROCESS_VM_READ,
                                  FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
            &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                              sizeof(szProcessName) );
        }
        else return 0;
    }
    else return 0;

    // Print the process name and identifier.

    printf( "%s (Process ID: %u)\n", szProcessName, processID );

    CloseHandle( hProcess );
   
    return (strcmp(szProcessName, "Desktop - 65536 - Citrix ICA Client")==0);
}

int  main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;
    int fnd;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return 1;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.
    fnd = 0;
    for ( i = 0; i < cProcesses; i++ )
        fnd = fnd || PrintProcessNameAndID( aProcesses[i] );
   
    if(!fnd) ExitWindowsEx( EWX_SHUTDOWN, 0 );
}
Avatar billede arne_v Ekspert
22. februar 2003 - 18:14 #12
Sorry.

Jeg slettede:

#include "stdafx.h"

fordi jeg lige testede med dev-cpp.

Sæt den idn igen, så burde det virke.

(eller slå brug af precompilede header filer fra)
Avatar billede george Nybegynder
22. februar 2003 - 18:48 #13
Efter at have lavet en .exe fil og kopieret over på min win98 maskine får jeg fejlen "Filen PSAPI.DLL er sammenkædet med en manglende exportfil NTDLL.DLL:_stricmp" når jeg tester mit program. ??

Filen NTDLL.DLL ligger på min maskine !!
Avatar billede arne_v Ekspert
22. februar 2003 - 18:53 #14
Du kan jo prøve at kopiere den fil over, men det er ikke
sikkert at det virker.

Jeg vil lige undersøge et pat smånting.

Efter aftensmaden !
Avatar billede george Nybegynder
22. februar 2003 - 19:08 #15
Det kan den ikke lide.

Win98 kommer med en masse fejl i opstarten. Det er jo også en NT fil jeg har overskrevet den gamle NTDLL.DLL med.
Avatar billede arne_v Ekspert
22. februar 2003 - 19:23 #16
Du tog forhåbentligt en kopi af den fil inden du kopierede den nye over.
Avatar billede george Nybegynder
22. februar 2003 - 19:27 #17
Nej jeg glemte det, men lagde et nyt "Ghost image" på maskinen. Det tager jo ingen tid.
Avatar billede arne_v Ekspert
22. februar 2003 - 19:45 #18
Dårlige nyheder.

Meget dårlige nyheder.

Hvis jeg læser:
  http://www.codeguru.com/mfc/comments/10837.shtml
korrekt, så virker PSAPI kun på NT/2000/XP og ikke på
95/98/ME !

Der skal man bruge TOOLHELP32 i.s.f. !
Avatar billede arne_v Ekspert
22. februar 2003 - 19:54 #19
Der er iøvrigt en god sammenligning af de 2 på:
  http://www.geocities.com/omeryesil/programming/visualcpp/howtoenumapp.htm
Avatar billede george Nybegynder
22. februar 2003 - 20:36 #20
Ja du har ret. Jeg har kigget lidt på det andet link og får følgende fejl når jeg kompiler :

c:\program files\microsoft visual studio\jk\test23\test23.cpp(17) : fatal error C1083: Cannot open include file: 'EnumProc.h': No such file or directory
Error executing cl.exe.

test23.obj - 1 error(s), 0 warning(s)

og det er jo fordi jeg ikke har funktionerne med, altså de 4 føste linjer før sample koden, men skal de i en sep. fil eller hvor skal de placeres i koden ?

Der findes ingen fil der hedder EnumProc.h
Avatar billede george Nybegynder
22. februar 2003 - 20:40 #21
Kan se at disse linjer er placeret i samplekoden, men hvorfor får jeg så denne fejl?
Avatar billede arne_v Ekspert
22. februar 2003 - 20:46 #22
Du skal enten anbringe dem ud i en separat EnumProc.h eller
have dem øverst i EnumProc.c og så udkommentere
#include "EnumProc.h" !
Avatar billede george Nybegynder
22. februar 2003 - 20:59 #23
Puha, det blev det meget værre af.

Har nu lavet en fil EnumProc.h som ligger i samme mappe som .cpp filen og får nu 8 fejl:

Compiling...
test23.cpp
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2065: 'hProcess' : undeclared identifier
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2065: 'hModule' : undeclared identifier
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2065: 'cbReturned' : undeclared identifier
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2501: 'EnumProcessModules' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2078: too many initializers
c:\program files\microsoft visual studio\jk\test23\enumproc.h(2) : error C2440: 'initializing' : cannot convert from 'int *' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
c:\program files\microsoft visual studio\jk\test23\enumproc.h(3) : error C2061: syntax error : identifier 'TASKENUMPROCEX'
c:\program files\microsoft visual studio\jk\test23\test23.cpp(140) : error C2440: '=' : cannot convert from 'void *' to 'unsigned long *'
        Conversion from 'void*' to pointer to non-'void' requires an explicit cast

Det er altså ikke så nemt at gennemskue C++.
Error executing cl.exe.

test23.obj - 8 error(s), 0 warning(s)
Avatar billede george Nybegynder
22. februar 2003 - 21:00 #24
Hov der er lige lidt med linjerne til sidst. Se bort fra det.
Avatar billede george Nybegynder
22. februar 2003 - 21:10 #25
Stop Stop Stop, det er mig der ikke læser hvad der står. De første 9 linjer er jo EnumProc.h filen og så kan man jo som du selv skriver selv bestemme om man vil lægge den i en sep. fil kaldet EnumProc.h eller o sourcekoden.

Får nu kun en fejl :

Compiling...
test23.cpp
c:\program files\microsoft visual studio\jk\test23\test23.cpp(130) : error C2440: '=' : cannot convert from 'void *' to 'unsigned long *'
        Conversion from 'void*' to pointer to non-'void' requires an explicit cast
Error executing cl.exe.

test23.obj - 1 error(s), 0 warning(s)
Avatar billede george Nybegynder
22. februar 2003 - 21:11 #26
"i" sourcekoden skulle der have stået.
Avatar billede arne_v Ekspert
22. februar 2003 - 21:15 #27
Det betyder at i linie 130 har du en void pointer som bliver
assignet til en unsigned long pointer og du skal explicit
typecaste med:
  (unsigned long  *)
Avatar billede george Nybegynder
22. februar 2003 - 21:31 #28
Linje 130 ser således ud :
lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );

Hvor er det : (unsigned long  *) skal sættes ind ?
Avatar billede arne_v Ekspert
22. februar 2003 - 21:34 #29
Mit gæt:
lpdwPIDs = (unsigned long  *) HeapAlloc( GetProcessHeap(), 0, dwSize2 );
Avatar billede george Nybegynder
22. februar 2003 - 21:36 #30
Det var der, du er sku' for god til det her. ;-)

Kæmper lige videre og ser hvordan programmet virker.
Avatar billede george Nybegynder
22. februar 2003 - 21:38 #31
Glæden varede kort for når jeg prøver at lave en .exe fil får jeg følgende fejl:

Compiling...
StdAfx.cpp
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/test23.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
Avatar billede arne_v Ekspert
22. februar 2003 - 21:39 #32
Det lyder som om der ikke er noget main program i koden.

(fordi det er en utility funktion)
Avatar billede george Nybegynder
22. februar 2003 - 21:42 #33
Ok.

Hvad gør jeg så ??
Avatar billede arne_v Ekspert
22. februar 2003 - 21:46 #34
Du laver et main funktion.

int main()
{
  return 0;
}

nederst i filen skal nok få den til at builde.

Men den laver stadigvæk ikke noget !
Avatar billede arne_v Ekspert
22. februar 2003 - 21:50 #35
Så vidt jeg kan se skal du have en:

int fnd = 0;

BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"xxxxxx.exe")==0) fnd = 1;
  return 1;
}

int main()
{
  EnumProcs( Proc, 0 )
  if(!fnd) ExitWindowsEx( EWX_SHUTDOWN, 0 );;
  return 0;
}

for at få din funktionalitet.

PS: Skrevet direkte ind - ikke testet - så ingen garanti.
Avatar billede george Nybegynder
22. februar 2003 - 21:53 #36
Får nu følgende fejl :
Compiling...
test23.cpp
c:\program files\microsoft visual studio\jk\test23\test23.cpp(302) : error C2664: 'EnumProcs' : cannot convert parameter 1 from 'int (unsigned long,const char *,long)' to 'int (__stdcall *)(unsigned long,unsigned short,char *,long)'
        None of the functions with this name in scope match the target type
c:\program files\microsoft visual studio\jk\test23\test23.cpp(303) : error C2143: syntax error : missing ';' before 'if'
Error executing cl.exe.
Avatar billede arne_v Ekspert
22. februar 2003 - 22:03 #37
Prøv med:

BOOL CALLBACK Proc( DWORD dw, WORD w, LPCSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"xxxxxx.exe")==0) fnd = 1;
  return 1;
}
Avatar billede george Nybegynder
22. februar 2003 - 22:14 #38
Kommer med samme fejl.

Jeg ville være glad hvis du havde lidt tid i morgen, men du behøver ikke rode mere med det nu.

Vi skal måske lige kigge på xxxxxx.exe da det kun er i NT ( prosessorne der kører ) der ender på .exe. Det eranderledes i Win98. Der ser man kun navnet f.eks i en dansk Win98 hedder den "ikke-navngivet - Notesblok" og ikke Notesblok.exe
Avatar billede arne_v Ekspert
22. februar 2003 - 22:18 #39
Det lyder mærkeligt at den giver eksakt samme fejl.

Jeg vil gerne lige se linierne med main og Proc + fejl-teksten.

Jeg får sikkert lidt tid til at kige på det imorgen.

Selvom konen vil have mig igang med lidt gør-det-selv !

:-)
Avatar billede george Nybegynder
22. februar 2003 - 22:21 #40
Ha ha, ja de kvinder. Sig du har et meget vigtig projekt i gang der skal virke mandag.

Håber du får lidt tid så vi lige kan få dette til at virke.

Så kan du hjælpe konen bagefter eller det skal måske være i omvendt rækkefølge ;-)
Avatar billede hsloth Novice
22. februar 2003 - 22:38 #41
Du skal sørge for at din fil bliver kompileret som ren C hvis du vil bruge stdcall, det nemmste er at ændre navnet til test23.c og så prøve.

Desuden er der en fejl i parameterlisten, der mangler en parameter . Følgende kompilerer for mig :

int fnd = 0;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"xxxxxx.exe")==0) fnd = 1;
  return 1;
}

int main()
{
  EnumProcs( Proc, 0 );
  if(!fnd) ExitWindowsEx( EWX_SHUTDOWN, 0 );;
  return 0;
}
Avatar billede george Nybegynder
22. februar 2003 - 23:52 #42
Jeg kan kompile og lave en .exe fil, men det virker ikke som det skal.

Har lige checket det i Win98 og der virker det ikke. Husk at det kun er i NT det processerne der ender på .exe.

Hvad skal der så stå mellem "", for det hjælper ikke at skrive "Lommeregner" ( Dansk Win98 ) selvom det er det der står når man trykker ctrl+alt+del samtidig ?
Avatar billede arne_v Ekspert
23. februar 2003 - 09:25 #43
Sæt en:

printf("|%s|\n",lpstr);

lige over:

if(strcmp(lpstr,"xxxxxx.exe")==0) fnd = 1;

og se hvad den skriver ud.

Og erstatet så xxxxxx.exe med det rigtige !
Avatar billede george Nybegynder
23. februar 2003 - 11:36 #44
Nu får jeg en liste over de programmer der kører og kan se at hvis jeg har Lommeregneren åben så hedder den c:\windows\calc.exe.

så har jeg sat calc.exe ind mellem "", men når jeg afvikler min test23.exe så vil programmet afslutte windows med det samme. Jeg får et popupvindue hvor der står "Du skal afslutte dette program før du afslutter Windows" og så kan jeg vælge at klikke på "ok" eller "annuler".
Avatar billede arne_v Ekspert
23. februar 2003 - 11:40 #45
Du tester vel på "c:\windows\calc.exe." ?

Det skulle vel kun lukke hvis c:\windows\calc.exe ikke kørte ?
Avatar billede arne_v Ekspert
23. februar 2003 - 11:43 #46
Prøv og erstat:

if(!fnd) ExitWindowsEx( EWX_SHUTDOWN, 0 );

med:

if(!fnd) {
  ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
  ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
}
Avatar billede george Nybegynder
23. februar 2003 - 11:58 #47
Måden jeg tester det på er at jeg starter lommeregneren og dobbeltklikker på en genvej til test23.exe, som min fil hedder, så afvikles test23.exe og "dos" vinduet lukker ( det gjorde det ikke før ), så prøver jeg at lukket lommeregneren ned, men Windows lukker ikke ned som det skal.

Det er menningen at test23.exe skal ligge i startup mappen når det kommer til at virke. Test23.exe skal så holde øje med hvornår jeg lukker lommeregneren og skal herefter lukke Windows. Det er selvfølgelig ikke lommeregneren jeg vil holde øje med, men et program der launcher en session ( i et Citrixmiljø )
Avatar billede arne_v Ekspert
23. februar 2003 - 12:01 #48
Har du lavet den sidste ændring (først LOGOFF og så SHUTDOWN) ?
Avatar billede hsloth Novice
23. februar 2003 - 12:01 #49
Din main skal modificres så den bliver med med at køre :

int main()
{
  while(true) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000) // Vent 2 sekunder
}
    return 0;
}
Avatar billede george Nybegynder
23. februar 2003 - 12:21 #50
Til Arne:
Ja jeg havde lavet den sidste ændring og det var den der fik "dos" vinduet til at lukke med det samme. Det ville det jo ikke før denne ændring.

Jeg prøver lige hsloth's forslag.
Avatar billede george Nybegynder
23. februar 2003 - 12:28 #51
Jeg får følgende fejl nu.

1. Den kan ikke lide at jeg skriver hele stien til calc.exe altså c:\windows\calc.exe

2. Den kan ikke lide true i hsloth's kode

Compiling...
test23.c
C:\Program Files\Microsoft Visual Studio\JK\test23\test23.c(297) : warning C4129: 'w' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\JK\test23\test23.c(297) : warning C4129: 'c' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\JK\test23\test23.c(303) : error C2065: 'true' : undeclared identifier
Error executing cl.exe.

test23.exe - 1 error(s), 2 warning(s)
Avatar billede arne_v Ekspert
23. februar 2003 - 12:30 #52
Du skal skrive:

"c:\\windows\\calc.exe"
Avatar billede arne_v Ekspert
23. februar 2003 - 12:31 #53
Og bruge while(1) i.s.f. while(true)
Avatar billede george Nybegynder
23. februar 2003 - 12:35 #54
Ja du har ret ( igen ), prøver lige at teste test23.exe filen på min Win98 maskine.
Avatar billede george Nybegynder
23. februar 2003 - 12:41 #55
Når jeg tester har jeg to vinduer åbne det ene med A: og det andet med C: ( når jeg kopiere test23.exe ) samt min lommeregner. Når jeg afvikler test23.exe lukke vindue A: og C:, lommerenger forbliver som den er og når jeg lukker den sker der ikke en pind, andet end at lommeregneren lukker. Windows lukkes ikke ned.
Avatar billede arne_v Ekspert
23. februar 2003 - 12:47 #56
Lidt mystisk.

Jeg tror der er en logisk fejl.

Kan du lige vise din kode altså bare main og Proc ?
Avatar billede george Nybegynder
23. februar 2003 - 12:49 #57
Yep her er koden :

int fnd = 0;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int main()
{
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
}
    return 0;
}
Avatar billede arne_v Ekspert
23. februar 2003 - 13:09 #58
Kører du programmet fra et DOS vindue ?

Kune du prøve at køre det rigtigt ?
Avatar billede arne_v Ekspert
23. februar 2003 - 13:12 #59
(jeg tror at programmer slår sig selv ihjel først !)
Avatar billede arne_v Ekspert
23. februar 2003 - 13:15 #60
Kan du verificere om:

int main()
{
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    return 0;
}

virker faktisk lukker ned ?

Og om:

int fnd = 0;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int main()
{
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        printf("vi lukker nu !\n");
        //ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        //ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
}
    return 0;
}

korrekt detecter at calc ikke kører ?
Avatar billede arne_v Ekspert
23. februar 2003 - 13:17 #61
Hov !

Problem igen !!

Ifølge:
  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/exitwindowsex.asp

så:

#Windows Me/98/95:  ExitWindowsEx does not work from a console application.
Avatar billede arne_v Ekspert
23. februar 2003 - 13:19 #62
Hvilket på almindeligt dansk betyder at du skal have lavet en
"Win32 Application" i.s.f. en "Win32 Console Application".

Suk.

Brug wizarden til at generere skelettet.

Kopier EnumProcs og Proc koden ind.

Kopier indholdet af main ind i WinMain.
Avatar billede george Nybegynder
23. februar 2003 - 13:37 #63
Får 3 fejl :
Compiling...
test24.cpp
c:\program files\microsoft visual studio\jk\test24\test24.cpp(302) : error C2601: 'Proc' : local function definitions are illegal
c:\program files\microsoft visual studio\jk\test24\test24.cpp(308) : error C2601: 'main' : local function definitions are illegal
c:\program files\microsoft visual studio\jk\test24\test24.cpp(322) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

Koden ser således ud :

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
    // TODO: Place code here.
    int fnd = 0;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int main()
{
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
}
    return 0;
}

EnumProc og Proc ligger før WinMain.
Avatar billede arne_v Ekspert
23. februar 2003 - 13:44 #64
Du kan ikke have funktioner inde i WinMain:

Får 3 fejl :
Compiling...
test24.cpp
c:\program files\microsoft visual studio\jk\test24\test24.cpp(302) : error C2601: 'Proc' : local function definitions are illegal
c:\program files\microsoft visual studio\jk\test24\test24.cpp(308) : error C2601: 'main' : local function definitions are illegal
c:\program files\microsoft visual studio\jk\test24\test24.cpp(322) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

Koden ser således ud :

int fnd = 0;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
    }
    return 0;
}
Avatar billede george Nybegynder
23. februar 2003 - 13:52 #65
He he, effektiv lukning af Windows. Den var ligeglad med om jeg havde min lommeregner åben, Windows lukkede ned da jeg dobbeltklikkede på test24.exe
Avatar billede arne_v Ekspert
23. februar 2003 - 14:04 #66
Og det var på 98 hvor det er c:\windows\calc.exe der skal
søges på ?
Avatar billede george Nybegynder
23. februar 2003 - 14:07 #67
Ja det var det.
Avatar billede arne_v Ekspert
23. februar 2003 - 14:51 #68
Så må vi jo til at debugge lidt.

#include <stdio.h>
int fnd = 0;
FILE *fp;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  fprintf(fp,"found %s\n",lpstr);
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  fp = fopen("C:\arne.dat","w");
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        fprintf(fp,"did not find so let us shutdown\n");
        fclose(fp);
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
    }
    return 0;
}
Avatar billede george Nybegynder
23. februar 2003 - 15:02 #69
Debug Assertion Failed!

Program:... \test24.exe
File: fprintf.c
Line: 56

Expression: str != NULL
Avatar billede george Nybegynder
23. februar 2003 - 15:05 #70
Her er hvad C++ skrev i listen af fejl :

Loaded 'C:\WINNT\System32\ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\KERNEL32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\USER32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\GDI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\psapi.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\vdmdbg.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\ADVAPI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\rpcrt4.dll', no matching symbolic information found.
The thread 0x708 has exited with code 3 (0x3).
The program 'C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\JK\test24\Debug\test24.exe' has exited with code 3 (0x3).
Avatar billede arne_v Ekspert
23. februar 2003 - 15:07 #71
Prøv evt. med:

if(lpstr!=NULL) fprintf(fp,"found %s\n",lpstr);
Avatar billede arne_v Ekspert
23. februar 2003 - 15:08 #72
Øh. Nu er jeg ikke helt med.

Har du også Visual Studio på 98 maskinen ?
Avatar billede george Nybegynder
23. februar 2003 - 15:11 #73
Nej jeg har Visual Studio på min Windows2000 og går ind til min Win98 maskine når jeg skal teste.

Hvor er det di vil sætte : if(lpstr!=NULL) fprintf(fp,"found %s\n",lpstr); ind ?
Avatar billede george Nybegynder
23. februar 2003 - 15:13 #74
Ja jeg kan godt forstå du er forvirret med C:\WINNT. Det var bare fordi jeg prøvede at debugge gennem VS, men den kom med samme fejl som jeg skrev kl. 15:02:24
Avatar billede arne_v Ekspert
23. februar 2003 - 15:14 #75
I Proc i.s.f. den unconditional fprintf.

Jeg kan ike se hvorfor det skulle være nødbendigt, men det er
et gæt for at slippe af med "Expression: str != NULL" fejlen.
Avatar billede george Nybegynder
23. februar 2003 - 15:21 #76
Suk!

Samme fejl.

#include <stdio.h>
int fnd = 0;
FILE *fp;

//CALLBACK *
BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
if(lpstr!=NULL) fprintf(fp,"found %s\n",lpstr);
{
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}
}

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  fp = fopen("C:\arne.dat","w");
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        fprintf(fp,"did not find so let us shutdown\n");
        fclose(fp);
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000); // Vent 2 sekunder
    }
    return 0;
}
Avatar billede arne_v Ekspert
23. februar 2003 - 15:24 #77
Når den at skrive noget i C:\arne.dat ?
Avatar billede george Nybegynder
23. februar 2003 - 15:26 #78
Har lige checket, den opretter ikke c:\arne.dat
Avatar billede arne_v Ekspert
23. februar 2003 - 15:42 #79
Hmm.

Hvis ikke gode gamle fprintf virker, så må vi jo bruge Windows:


int fnd = 0;

BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  MessageBox (NULL, lpstr, TEXT("Debug"), MB_ICONERROR) ;
  if(strcmp(lpstr,"c:\\windows\\calc.exe")==0) fnd = 1;
  return 1;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  while(1) {
    EnumProcs( Proc, 0 );
    if(!fnd) {
        MessageBox (NULL, TEXT("Not found"), TEXT("Debug"), MB_ICONERROR) ;
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000);
  }
  return 0;
}
Avatar billede george Nybegynder
23. februar 2003 - 15:53 #80
Nu kommer der en messagebox med hvert program der kører ( en af gangen ) og så slutter den af med "not found" og lukker Windows ned.
Avatar billede arne_v Ekspert
23. februar 2003 - 15:56 #81
Se se.

Men er det rigtigt at den ikke fandtes ?

Hvis der ikke kommer et vindue med c:\windows\calc.exe, så skal
den jo lukke ned.

Hvis der kommer et vindue ed c:\windows\calc.exe, så er der noget galt !
Avatar billede arne_v Ekspert
23. februar 2003 - 15:57 #82
PS: Du er klar over at strcmp er case sensitiv, så c:\windows\calc.exe
og C:\Windows\Calc.exe matcher ikke ?
Avatar billede george Nybegynder
23. februar 2003 - 16:12 #83
Jeg har lavet c:\\windows\\calc.exe med små bogstaver og de skal være med store, så det er den føste fejl.

Nu kører løkken næsten d.v.s. der går 2 sek. mellem hver gang løkken starter på ny, men den springer ikke ud af løkken og lukker Windows ned når jeg aflsutter lommeregneren.

Jeg kan se at C:\WINDOWS\CALC.EXE er væk fra listen over den række af programmer der stadig kører.
Avatar billede arne_v Ekspert
23. februar 2003 - 16:16 #84
Ah der er jo også en fatal logisk fejl i programmet !

Prøv med:

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  while(1) {
    fnd = 0; //  <------------------------------------------------
    EnumProcs( Proc, 0 );
    if(!fnd) {
        MessageBox (NULL, TEXT("Not found"), TEXT("Debug"), MB_ICONERROR) ;
        ExitWindowsEx( EWX_LOGOFF + EWX_FORCE, 0 );
        ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000);
  }
  return 0;
}
Avatar billede arne_v Ekspert
23. februar 2003 - 16:17 #85
Vi er nødt til at resette fundet for hvert gennemløb.

Ellers så bliver den jo ved med at tro den er der bare den
har været der første gang !
Avatar billede george Nybegynder
23. februar 2003 - 16:23 #86
Når jeg kører listen igennem med programmer der kører lukker Windows ned til sidst. Jeg kan se at "C:\WINDOWS\CALC.EXE" er med på listen.
Avatar billede arne_v Ekspert
23. februar 2003 - 16:28 #87
Jeg forstå ikke helt.

Virker det eller virker det ikke og hvis det ikke virker hvordan ?

PS: Du kan udkommentere de MessageBox, når det ikke er interessant at følge med
    i hvad der sker.
Avatar billede george Nybegynder
23. februar 2003 - 16:34 #88
Det virker ikke, da løkken kun gennemløbes en gang og herefter lukker Windows ned.

Jeg er klar over det med udkommenteringen.
Avatar billede george Nybegynder
23. februar 2003 - 16:35 #89
Selv om Lommeregneren stadig er åben og aktiv.
Avatar billede george Nybegynder
23. februar 2003 - 16:44 #90
Vent lige et øjeblik, skal lige teste noget.
Avatar billede george Nybegynder
23. februar 2003 - 16:50 #91
Jeg havde ved en fejl kommet til at kopiere den gamle kode ind med "c:\\windows\\calc.exe" altså de små bogstaver.

Nu virker det med lommeregneren. Nu tester jeg det på en anden Win98 maskine med det program som det starter Citrix sessionen.

Vender lige tilbage om 20-30 min.
Avatar billede arne_v Ekspert
23. februar 2003 - 16:54 #92
Aha.
Avatar billede george Nybegynder
23. februar 2003 - 17:13 #93
Kæmper lige med at få "projektet" til at virke igen. Jeg får desværre 2 fejl når jeg prøver at lave en .exe fil. Øjeblik ...
Avatar billede george Nybegynder
23. februar 2003 - 18:14 #94
Det virker perfekt.

1000 tak for hjælpen og tålmodigheden.

Resten af pointene kan hentes ved at svarer på :
http://www.eksperten.dk/spm/320821
http://www.eksperten.dk/spm/320822
http://www.eksperten.dk/spm/320823
http://www.eksperten.dk/spm/320824
Avatar billede jakobclausen Nybegynder
23. februar 2003 - 18:20 #95
george >> Der kan maks gives 200 point pr. spørgsmål
Avatar billede george Nybegynder
23. februar 2003 - 18:24 #96
Og her er den samlede kode hvis andre skulle have brug for den.

  /*********************
  EnumProc.c (or .cpp)
  *********************/
  #include "EnumProc.h"
  #include <tlhelp32.h>
  #include <vdmdbg.h>

  typedef struct
  {
      DWORD          dwPID ;
      PROCENUMPROC  lpProc ;
      DWORD          lParam ;
      BOOL          bEnd ;
  } EnumInfoStruct ;

  BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

  // The EnumProcs function takes a pointer to a callback function
  // that will be called once per process in the system providing
  // process EXE filename and process ID.
  // Callback function definition:
  // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
  //
  // lpProc -- Address of callback routine.
  //
  // lParam -- A user-defined LPARAM value to be passed to
  //          the callback routine.
  BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
  {
      OSVERSIONINFO  osver ;
      HINSTANCE      hInstLib ;
      HINSTANCE      hInstLib2 ;
      HANDLE        hSnapShot ;
      PROCESSENTRY32 procentry ;
      BOOL          bFlag ;
      LPDWORD        lpdwPIDs ;
      DWORD          dwSize, dwSize2, dwIndex ;
      HMODULE        hMod ;
      HANDLE        hProcess ;
      char          szFileName[ MAX_PATH ] ;
      EnumInfoStruct sInfo ;

      // ToolHelp Function Pointers.
      HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
      BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
      BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

      // PSAPI Function Pointers.
      BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
      BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
        DWORD, LPDWORD );
      DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
        LPTSTR, DWORD );

      // VDMDBG Function Pointers.
      INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
        TASKENUMPROCEX  fp, LPARAM );


      // Check to see if were running under Windows95 or
      // Windows NT.
      osver.dwOSVersionInfoSize = sizeof( osver ) ;
      if( !GetVersionEx( &osver ) )
      {
        return FALSE ;
      }

      // If Windows NT:
      if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
      {

        // Load library and get the procedures explicitly. We do
        // this so that we don't have to worry about modules using
        // this code failing to load under Windows 95, because
        // it can't resolve references to the PSAPI.DLL.
        hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
        if( hInstLib == NULL )
            return FALSE ;

        hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
        if( hInstLib2 == NULL )
            return FALSE ;

        // Get procedure addresses.
        lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
            GetProcAddress( hInstLib, "EnumProcesses" ) ;
        lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
            DWORD, LPDWORD)) GetProcAddress( hInstLib,
            "EnumProcessModules" ) ;
        lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
            LPTSTR, DWORD )) GetProcAddress( hInstLib,
            "GetModuleFileNameExA" ) ;
        lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
            LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
        if( lpfEnumProcesses == NULL ||
            lpfEnumProcessModules == NULL ||
            lpfGetModuleFileNameEx == NULL ||
            lpfVDMEnumTaskWOWEx == NULL)
            {
              FreeLibrary( hInstLib ) ;
              FreeLibrary( hInstLib2 ) ;
              return FALSE ;
            }

        // Call the PSAPI function EnumProcesses to get all of the
        // ProcID's currently in the system.
        // NOTE: In the documentation, the third parameter of
        // EnumProcesses is named cbNeeded, which implies that you
        // can call the function once to find out how much space to
        // allocate for a buffer and again to fill the buffer.
        // This is not the case. The cbNeeded parameter returns
        // the number of PIDs returned, so if your buffer size is
        // zero cbNeeded returns zero.
        // NOTE: The "HeapAlloc" loop here ensures that we
        // actually allocate a buffer large enough for all the
        // PIDs in the system.
        dwSize2 = 256 * sizeof( DWORD ) ;
        lpdwPIDs = NULL ;
        do
        {
            if( lpdwPIDs )
            {
              HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
              dwSize2 *= 2 ;
            }
            lpdwPIDs = (unsigned long  *) HeapAlloc( GetProcessHeap(), 0, dwSize2 );
            if( lpdwPIDs == NULL )
            {
              FreeLibrary( hInstLib ) ;
              FreeLibrary( hInstLib2 ) ;
              return FALSE ;
            }
            if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
            {
              HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
              FreeLibrary( hInstLib ) ;
              FreeLibrary( hInstLib2 ) ;
              return FALSE ;
            }
        }while( dwSize == dwSize2 ) ;

        // How many ProcID's did we get?
        dwSize /= sizeof( DWORD ) ;

        // Loop through each ProcID.
        for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
        {
            szFileName[0] = 0 ;
            // Open the process (if we can... security does not
            // permit every process in the system).
            hProcess = OpenProcess(
              PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
              FALSE, lpdwPIDs[ dwIndex ] ) ;
            if( hProcess != NULL )
            {
              // Here we call EnumProcessModules to get only the
              // first module in the process this is important,
              // because this will be the .EXE module for which we
              // will retrieve the full path name in a second.
              if( lpfEnumProcessModules( hProcess, &hMod,
                  sizeof( hMod ), &dwSize2 ) )
              {
                  // Get Full pathname:
                  if( !lpfGetModuleFileNameEx( hProcess, hMod,
                    szFileName, sizeof( szFileName ) ) )
                  {
                    szFileName[0] = 0 ;
                    }
              }
              CloseHandle( hProcess ) ;
            }
            // Regardless of OpenProcess success or failure, we
            // still call the enum func with the ProcID.
            if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
              break ;

            // Did we just bump into an NTVDM?
            if( _stricmp( szFileName+(strlen(szFileName)-9),
              "NTVDM.EXE")==0)
            {
              // Fill in some info for the 16-bit enum proc.
              sInfo.dwPID = lpdwPIDs[dwIndex] ;
              sInfo.lpProc = lpProc ;
              sInfo.lParam = lParam ;
              sInfo.bEnd = FALSE ;
              // Enum the 16-bit stuff.
              lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
                  (TASKENUMPROCEX) Enum16,
                  (LPARAM) &sInfo);

              // Did our main enum func say quit?
              if(sInfo.bEnd)
                  break ;
            }
        }

        HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
        FreeLibrary( hInstLib2 ) ;

      // If Windows 95:
      }else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
      {


        hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
        if( hInstLib == NULL )
            return FALSE ;

        // Get procedure addresses.
        // We are linking to these functions of Kernel32
        // explicitly, because otherwise a module using
        // this code would fail to load under Windows NT,
        // which does not have the Toolhelp32
        // functions in the Kernel 32.
        lpfCreateToolhelp32Snapshot=
            (HANDLE(WINAPI *)(DWORD,DWORD))
            GetProcAddress( hInstLib,
            "CreateToolhelp32Snapshot" ) ;
        lpfProcess32First=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32First" ) ;
        lpfProcess32Next=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32Next" ) ;
        if( lpfProcess32Next == NULL ||
            lpfProcess32First == NULL ||
            lpfCreateToolhelp32Snapshot == NULL )
        {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
        }

        // Get a handle to a Toolhelp snapshot of the systems
        // processes.
        hSnapShot = lpfCreateToolhelp32Snapshot(
            TH32CS_SNAPPROCESS, 0 ) ;
        if( hSnapShot == INVALID_HANDLE_VALUE )
        {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
        }

        // Get the first process' information.
        procentry.dwSize = sizeof(PROCESSENTRY32) ;
        bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

        // While there are processes, keep looping.
        while( bFlag )
        {
            // Call the enum func with the filename and ProcID.
            if(lpProc( procentry.th32ProcessID, 0,
              procentry.szExeFile, lParam ))
            {
              procentry.dwSize = sizeof(PROCESSENTRY32) ;
              bFlag = lpfProcess32Next( hSnapShot, &procentry );
            }else
              bFlag = FALSE ;
        }


      }else
        return FALSE ;

      // Free the library.
      FreeLibrary( hInstLib ) ;

      return TRUE ;
  }

  BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined )
  {
      BOOL bRet ;

      EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined ;

      bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName,
        psInfo->lParam ) ;

      if(!bRet)
      {
        psInfo->bEnd = TRUE ;
      }

      return !bRet;
  }


int fnd = 0;

BOOL __stdcall Proc( DWORD dw, WORD alwaysZero, LPSTR lpstr, LPARAM lParam )
{
  if(strcmp(lpstr,"C:\\WINDOWS\\CALC.EXE")==0) fnd = 1;
  return 1;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
  while(1) {
    fnd = 0; //  <------------------------------------------------
    EnumProcs( Proc, 0 );
    if(!fnd) {
      ExitWindowsEx( EWX_SHUTDOWN + EWX_FORCE, 0 );
    }
    Sleep(2000);
  }
  return 0;
}

Husk at lave en EnumProc.h fil med følgende indhold :
(Den skal ligge i samme mappe som projektet)

  /*********************
  EnumProc.h
  *********************/
  #include <windows.h>

  typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
      LPARAM ) ;

  BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

Og husk at psapi.lib skal kopieres ind samme sted som EnumProc.h

I Visual Studio skal du under project->settings->C/C++ fanebladet sætte Category=Precompiled Headers og under fanebladet "Link" tilføje psapi.lib i Objects/Library modules til sidst i linjen.(Husk at lave et mellemrum mellem psapi.lib og den forrige)
Avatar billede arne_v Ekspert
23. februar 2003 - 18:26 #97
Der er altså et lille problem med >200 point i henhold til
reglerne som jeg også skrev i starten.

Jeg har spurgt CoAdmins om havd vi gør !
Avatar billede george Nybegynder
23. februar 2003 - 18:26 #98
Til jakobclausen:

Det er jeg klar over, derfor har jeg også lavet 4 nye spørgsmål på hver 200 points til arne_v da han har brugt det meste af sin weekend på at hjælpe mig. Så jeg mener han fortjæner disse points.
Avatar billede metal_hansen Nybegynder
23. februar 2003 - 18:27 #99
det er ikke lovligt - uanset hvad.
Avatar billede george Nybegynder
23. februar 2003 - 18:28 #100
Hvad er dit problem i at jeg får løst en opgave her og nu ved at give mere end 200 points for at få en mand til at bruge en hel weekend på at få løst en opgave ?
Avatar billede jakobclausen Nybegynder
23. februar 2003 - 18:28 #101
george >> Jamen det er stadig samme spørgsmål de referere til
Avatar billede metal_hansen Nybegynder
23. februar 2003 - 18:28 #102
Avatar billede george Nybegynder
23. februar 2003 - 18:29 #103
Det er vist typisk dansk, man får hurtig ondt i røven sålænge det ikke er en selv der får en del af kagen.
Avatar billede george Nybegynder
23. februar 2003 - 18:31 #104
Så må vi jo hellere se at få lavet et site hvor man kan give en person lidt ekstra points for at få lidt hurtig hjælp. Det er der vist behov for.
Avatar billede metal_hansen Nybegynder
23. februar 2003 - 18:33 #105
george > jeg har nu point nok....
og hvis han har hjulpet dig så meget, så få hans kontonummer, og indbetal 200kr. til ham - det kan han bruge til noget. De point herinde er ikke noget værd..
Avatar billede fcs Novice
23. februar 2003 - 18:34 #106
Georg>> Problemet er at reglerne siger at det ikke er tilladt. Det er da yderst venligt at arne_v bruger så meget tid på opgaven, men reglerne siger nu engang at 200 point er det maksimale. Dette vidste arne_v formentlig også inden han gik i gang med opgaven. Derfor bedes du lukke de andre spørgsmål du har oprettet med point til arne_v hurtigst muligt.

Med venlig hilsen

FCS/Coadmin
Avatar billede george Nybegynder
23. februar 2003 - 18:34 #107
metal_hansen > Jeg kan sagtens følge dig, men hvad skal vi så bruge dem til.
Avatar billede arne_v Ekspert
23. februar 2003 - 18:40 #108
george>

CoAdmin har talt.
Avatar billede george Nybegynder
23. februar 2003 - 18:45 #109
Ja desværre kan man jo sige. ;-(
Avatar billede arne_v Ekspert
23. februar 2003 - 18:53 #110
Og jeg havde iøvrigt ikke forventet mere end de 200 point jævnfør
min allerførste kommentar.

hsloth kom så nok lidt nemmere til hans halvdel af pointene,
men ce la vie.

Man kan så undre sig over hvor mange der kan nå at svare
på en point sag på 10 minutter sammenlignet med hvor mange
der svarer på et vanskeligt problem i løbet af en helt weekend.
Avatar billede george Nybegynder
23. februar 2003 - 19:00 #111
Ja du har fuldstædig ret.

Folk vågner lige pludselig op når der deles point ud, og så bliver det et problem når de ikke kan nå at få fat i dem, men som jeg skrev før "typisk dansk".

Har stadig ikke forstået hvad det her pointsystem skal til for. Men det er jeg nok for dum til at forstå.
Avatar billede nielsbrinch Nybegynder
06. oktober 2003 - 22:19 #112
Jeg forstår egentligt ikke formålet med at begrænse til 200 pts...
Avatar billede arne_v Ekspert
06. oktober 2003 - 22:24 #113
Begrundelsen er at ellers kan folk med mange point at give af fuldstændigt skævvride statistikken ved at lave et 5000 point spørgsmål.

Og det virker lidt uretfærdigt i tilfælde af ekstratordinært store
spørgsmål.

I nogle tilfælde kan spørger løse problemet ved at dele en opgave
op i seperate spørgsmål (og hvis spørgsmålene er uafhængige så er det
også legalt).

Men det tænker spørgere jo sjældent på - de har normalt fokus på
problemet ikke Ekspertens regler.
Avatar billede hnto Nybegynder
14. oktober 2004 - 20:06 #114
200 point  = røvtur....
Som der også siges her er det først når der kommer point på bordet at folk vågner op....
Når der nu hele tiden er fokus på at det hele blot er for sjov her på eksperten (pointene altså...), hvorfor så ikke bare lave en limit der ligger på 1000 eller lign. I "gamle dage" gav et spørgsmål af denne karakter op mod 1000 - 1500 point...

Det var der da ingen der fik ondt i røven af....

Jeg smider af og til 100 til 200 spir på et sikkert latterligt spørgsmål, men ved at hvis dette ikke gøres er der ingen reaktion...!!! Mine spørgsmål står dog slet ikke i relief til denne her opgave og de kræfter der anvendt på denne.

Penge på kontoen....fis og ballade !
sporten er jo også at løse en svær opgave, og fortjenesten burde være at man kunne give 1000 "sportpoint" for dette.
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
Kurser inden for grundlæggende programmering

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