Toon posts:

[c++] Createprocess en mailslots

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo lieden ik heb de volgende code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <windows.h>
#include <iostream>

void main()

{
  // Set the startup information
  STARTUPINFO startup_info = {0};
  startup_info.cb = sizeof startup_info;
  PROCESS_INFORMATION pi = {0};

  // Create the process
 CreateProcess( "D:\\ipc\\opdracht\\debug\\printer.exe", 
                "D:\\ipc\\opdracht\\debug\\printer.exe", 
                NULL, NULL, FALSE, 0, NULL, NULL, &startup_info, &pi);
}

Waarbij "printer.exe" een file is die steeds A, B, C, A enzovoorts onder elkaar print. Maar nu is de bedoeling dat mijn Main niet 1 dos box met dat proggie start maar 3, simpelweg de code 3x uitvoeren schijnt niet te werken....

Dit programma is trouwens onderdeel van een programma wat uiteindelijk met behulp van mailslots eerst alle dos boxen een A moet laten printen dan een B en dan een C alvorens het verhaal opnieuw begint.

en ja het is een huiswerk opdracht, maar ik vraag niet of jullie hem willen maken maar of jullie mij gewoon willen helpen.

Verwijderd

ik ben aardig n00b als het gaat om win32, maar ik zie in mn docs gewoon
CREATE_NEW_CONSOLE
als optie staan bij de dwCreationFlags (6e parameter)

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Beetje de standaardvraag, maar wat werkt er dan niet?
Als ik het goed belees, zullen er waarschijnlijk geen 3 dos boxen gemaakt worden. In dat geval zou ik nog maar eens goed op msdn zoeken naar documentatie van CreateProcess...

Edit: als je een subtiele hint wilt intypen, ben je altijd te laat :'(

[ Voor 13% gewijzigd door SWfreak op 01-03-2004 16:37 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
%WINDIR%\CMD.EXE MyBatchFile.CMD ?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Verwijderd schreef op 01 maart 2004 @ 16:35:
ik ben aardig n00b als het gaat om win32, maar ik zie in mn docs gewoon
CREATE_NEW_CONSOLE
als optie staan bij de dwCreationFlags (6e parameter)
Euh... 8)7 hoe kon ik die missen... Sorry echt glad overheen gekeken!! In iedergeval bedankt! Ik kijk even verder wat ik nu allemaal kan uitspoken met synchronisatie mbv mailslots... Tips en Trucs blijven welkom natuurlijk!

  • klinz
  • Registratie: Maart 2002
  • Laatst online: 21-05 09:01

klinz

weet van NIETS

Je kunt met:
code:
1
WaitForSingleObject(pi.hProcess, INFINITE);  // pi = PROCESS_INFORMATION

Wachten tot het proces klaar is.

Verwijderd

Topicstarter
Ik wil dus een programma maken dat drie dos boxen opent die dan a,b,c printen. Dus eerst doet de eerste dosbox A dan print de 2e een A en als laatste de 3e ook. Als dit gebeurd is dan zouden ze een B moeten printen en zo verder tot in den treure.

Dit is wat ik nu heb:

Dit is het programma wat de chars print op het scherm, en deze heeft dus een mailslot.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdio.h"
#include "windows.h"

void showChar(char character)
{  
    printf("character= %c \n",character);   
}

int main(int argc,char * argv[]){   
    
HANDLE hSlot = CreateMailslot("\\\\.\\mailslot\\msname", 0,  MAILSLOT_WAIT_FOREVER,  NULL);

while (TRUE)
{
  ReadFile(hSlot, buf, sizeof(buf), &dwRead, NULL); // receive message from master.
  showChar(buf);// print what the master has told us to.
}   
return 0;
}



En dit is de code dusver voor het 'hoofdprogramma'
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <windows.h>
#include <iostream>

void main()

{
  // Set the startup information
  STARTUPINFO startup_info = {0};
  startup_info.cb = sizeof startup_info;
  PROCESS_INFORMATION pi = {0};
  character = 'a';

  // Create the process
  CreateProcess("D:\\prog\\debug\\printer.exe", 
                "D:\\prog\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
  
  CreateProcess("D:\\prog\\debug\\printer.exe", 
                "D:\\prog\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
  
  CreateProcess("D:\\prog\\debug\\printer.exe", 
                "D:\\prog\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

    // Connect to mailslots.
    hSlot1 = CreateFile("\\\\.\\mailslot\\msname" ,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

    // Write to mailslots what you want them to output.
    WriteFile(hSlot1, character, sizeof(character),(LPDWORD) &n,NULL);
}


Wat ik nu mee zit is het volgende:

- de mailslots moeten elk een andere naam hebben, maar hoe kan ik dit het beste doen? Is de naam meegeven op de command line een idee? :?
-de var 'character' zou character++ moeten worden nadat alle 3 dos boxen klaar zijn en daarna kan het riedeltje weer opnieuw met character++. daartoe zou ik de WRITEFILE file in een for loopje moeten gooien, correcto? Is dat de beste weg? Of ander de makkelijkste! :Y)

Verder wil ik even opmerken dat ik dus niet alwetend ben op het gebied van C, win32 programmeren is zo mogelijk nog nieuwer en het idee mailslots begin ik sinds nu pas echt mee.... wat ik er van kan vinden op het internet is nogal redelijk abstract gebracht, vandaar dat ik mijn geluk hiereens probeer! :>

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Merged met vorige topic, en let voortaan even op die titel ;)

Professionele website nodig?


Verwijderd

Topicstarter
Nou lieden ik heb even verder geprutst met dit als resultaat aan code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <windows.h>
#include <iostream>

void main()

{
  // Set the startup information
  HANDLE hSlot1;
  STARTUPINFO startup_info = {0};
  PROCESS_INFORMATION pi = {0};

  startup_info.cb = sizeof startup_info;

  int n;
  char toPrint = 'a';
  char msname[30] = "";

  // Create the process
  /*strcpy(msname, "slot1");
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                "D:\\ipc\\opdracht\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
  
    strcpy(msname, "slot2");
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                "D:\\ipc\\opdracht\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);*/
  
    strcpy(msname, "slot3");
    CreateProcess("D:\\ipc\\opdracht\\debug\\print.exe", 
                msname, 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

    // Connect to mailslots.
    hSlot1 = CreateFile(strcat("\\\\.\\mailslot\\" ,msname),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_E
XISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    // Write to mailslots what you want them to output.
    WriteFile(hSlot1, &toPrint, sizeof(toPrint),(LPDWORD)&n,NULL);

    CloseHandle(hSlot1);
}



code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "stdio.h"
#include "windows.h"

void showChar(char * character)
{  
    printf("character= %c \n",&character);  
}

int main(int argc,char * argv[]){   
    
    int dwRead;

    HANDLE hSlot = CreateMailslot(argv[1], 0,  MAILSLOT_WAIT_FOREVER,  NULL);

    while (TRUE)
    {
        ReadFile(hSlot, argv[1], sizeof(argv[1]), (LPDWORD)&dwRead, NULL);  // Receive message from master.
        showChar(??);                                       // print what the master has told us to.
    }
    return 0;
}


Nou het zwikkie werkt nog niet, er wordt alleen 'character = (' geprint. :(

Ik zit op het moment met deze vragen:
In het hoofdprogramma heb ik een variabel n gebruikt om de code te laten compileren, ik gebruik deze var alleen in de functieaanroep verder niet, zou dit wel moeten?


in het 'slave' programma heb ik een mailslot gemaakt met een naam die ik in de server heb opgegeven, maar komt die wel door? ik krijg het niet uitgevogeld.
:'(
Bovendien wil ik de showchar een character laten printen die ik in de server opgeef (nu 'a'), maar hoe moet ik dat doorgeven aan mijn showchar? Ik kan denk ik niet argv[1] gebruiken omdat daar de naam van de mailslot zou moeten staan....
Ik denk dat in argv[1] nu OF de naam van het mailslot staat OF het character wat geprint moet worden.

Verder twijfel ik nog of zowel de mailslot naam als het opgegeven character in het main programma goed doorkomen dan wel goed opgegeven zijn....

Verwijderd

Verwijderd schreef op 03 maart 2004 @ 17:15:
Nou lieden ik heb even verder geprutst met dit als resultaat aan code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <windows.h>
#include <iostream>

void main()

{
  // Set the startup information
  HANDLE hSlot1;
  STARTUPINFO startup_info = {0};
  PROCESS_INFORMATION pi = {0};

  startup_info.cb = sizeof startup_info;

  int n;
  char toPrint = 'a';
  char msname[30] = "";

  // Create the process
  /*strcpy(msname, "slot1");
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                "D:\\ipc\\opdracht\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
  
    strcpy(msname, "slot2");
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                "D:\\ipc\\opdracht\\debug\\printer.exe", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);*/
  
    strcpy(msname, "slot3");
    CreateProcess("D:\\ipc\\opdracht\\debug\\print.exe", 
                msname, 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

    // Connect to mailslots.
    hSlot1 = CreateFile(strcat("\\\\.\\mailslot\\" ,msname),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_E
XISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    // Write to mailslots what you want them to output.
    WriteFile(hSlot1, &toPrint, sizeof(toPrint),(LPDWORD)&n,NULL);

    CloseHandle(hSlot1);
}



code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "stdio.h"
#include "windows.h"

void showChar(char * character)
{  
    printf("character= %c \n",&character);  
}

int main(int argc,char * argv[]){   
    
    int dwRead;

    HANDLE hSlot = CreateMailslot(argv[1], 0,  MAILSLOT_WAIT_FOREVER,  NULL);

    while (TRUE)
    {
        ReadFile(hSlot, argv[1], sizeof(argv[1]), (LPDWORD)&dwRead, NULL);  // Receive message from master.
        showChar(??);                                       // print what the master has told us to.
    }
    return 0;
}


Nou het zwikkie werkt nog niet, er wordt alleen 'character = (' geprint. :(

Ik zit op het moment met deze vragen:
In het hoofdprogramma heb ik een variabel n gebruikt om de code te laten compileren, ik gebruik deze var alleen in de functieaanroep verder niet, zou dit wel moeten?


in het 'slave' programma heb ik een mailslot gemaakt met een naam die ik in de server heb opgegeven, maar komt die wel door? ik krijg het niet uitgevogeld.
:'(
Bovendien wil ik de showchar een character laten printen die ik in de server opgeef (nu 'a'), maar hoe moet ik dat doorgeven aan mijn showchar? Ik kan denk ik niet argv[1] gebruiken omdat daar de naam van de mailslot zou moeten staan....
Ik denk dat in argv[1] nu OF de naam van het mailslot staat OF het character wat geprint moet worden.

Verder twijfel ik nog of zowel de mailslot naam als het opgegeven character in het main programma goed doorkomen dan wel goed opgegeven zijn....
1. Check altijd de returnwaardes van de aangeroepen functies.
Bijvoorbeeld van CreateFile, CreateMailslot, WriteFile, etc.
2. Vergeet argv[1]. Deze is nergens voor nodig.
3. Gebruik als mailslot een combinatie van een "naam + pid". De pid krijg je terug van CreateProcess. En kun je in de client programma ophalen met GetCurrentProcessId()
4. De CreateProcess geeft onder meer twee handles terug die je moet vrijgeven met CloseHandle. Deze zijn te vinden in pi.
5. Waarom schrijf je in de ReadFile naar argv[1]? Je moet een buffer klaar hebben staan die groot genoeg is voor de in te lezen data.
6. Wellicht moet je nog ff een sleep tussen het aanmaken van de drie processen en het openen van de client mailslot invoegen, omdat je anders wellicht al naar de mailslot zou kunnen proberen te schrijven terwijl de client mailslot nog niet aangemaakt is.


Delphi rulez!
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
program Producer;

uses
  Windows, SysUtils;

{$APPTYPE CONSOLE}

var
  hMailslot: THandle;
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
  ProcessId: array[0..2] of THandle;
  toPrint: char;
  NumberOfBytesWritten: DWORD;
begin
  ZeroMemory(@StartupInfo,SizeOf(StartupInfo));
  ProcessId[0] := 0;
  ProcessId[1] := 0;
  ProcessId[2] := 0;

  toPrint := 'a';

  StartupInfo.cb := SizeOf(StartupInfo);

  if CreateProcess('printer.exe',Nil,Nil,Nil,False,CREATE_NEW_CONSOLE,Nil,Nil,StartupInfo,ProcessInformation) then
  try
     ProcessId[0] := ProcessInformation.dwProcessId;
  finally
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
  end;

  if CreateProcess('printer.exe',Nil,Nil,Nil,False,CREATE_NEW_CONSOLE,Nil,Nil,StartupInfo,ProcessInformation) then
  try
    ProcessId[1] := ProcessInformation.dwProcessId;
  finally
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
  end;

  if CreateProcess('printer.exe',Nil,Nil,Nil,False,CREATE_NEW_CONSOLE,Nil,Nil,StartupInfo,ProcessInformation) then
  try
     ProcessId[2] := ProcessInformation.dwProcessId;
  finally
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
  end;

  Sleep(3000);

  // Connect to mailslot
  hMailSlot := CreateFile(PChar('\\.\mailslot\msn' + IntToStr(ProcessId[2])),GENERIC_WRITE,FILE_SHARE_READ,Nil,OPEN_EXISTING,0,0);
  if (hMailSlot <> INVALID_HANDLE_VALUE) then
  try
    WriteFile(hMailSlot,toPrint,Length(toPrint),NumberOfBytesWritten,Nil);
  finally
    CloseHandle(hMailslot);
  end;
end.


Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
program Printer;

uses
  Windows, SysUtils;

{$APPTYPE CONSOLE}

procedure ShowChar(character: string);
begin
  WriteLn('character= ' + character);
end;

var
  NumberOfBytesRead: DWORD;
  hMailslot: THandle;
  toPrint: char;
begin
  hMailSlot := CreateMailSlot(PChar('\\.\mailslot\msn' + IntToStr(GetCurrentProcessId)),1,MAILSLOT_WAIT_FOREVER,Nil);
  if (hMailSlot <> INVALID_HANDLE_VALUE) then
  try
    while true do
    begin
      ReadFile(hMailSlot,toPrint,Length(toPrint),NumberOfBytesRead,Nil);
      ShowChar(toPrint);
    end;
  finally
    CloseHandle(hMailSlot);
  end;
end.

[ Voor 35% gewijzigd door Verwijderd op 04-03-2004 00:23 . Reden: voorbeeld code ]


Verwijderd

Topicstarter
hmm ok ik dacht dat ik het had... niet dus... ik zal even de code neer plempen en vertellen wat er gebeurt:

Hier wederom de code van het hoofdprogramma
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <windows.h>
#include <iostream>

void main()

{
  // Set the startup information
  HANDLE hSlot1, hSlot2,hSlot3;
  STARTUPINFO startup_info = {0};
  PROCESS_INFORMATION pi = {0};

  startup_info.cb = sizeof startup_info;

  DWORD dwWritten;
  char toPrint = 'a';

  // Create the process
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                " \\\\.\\mailslot\\slot1", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);
  
    CreateProcess("D:\\ipc\\opdracht\\debug\\printer.exe", 
                " \\\\.\\mailslot\\slot2", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

    CreateProcess("D:\\ipc\\opdracht\\debug\\print.exe", 
                " \\\\.\\mailslot\\slot3", 
                NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &pi);

    // Connect to mailslots.
    hSlot1 = CreateFile("\\\\.\\mailslot\\slot1",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    printf("Slot1 gemaakt\n");
    hSlot2 = CreateFile("\\\\.\\mailslot\\slot2",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    printf("Slot2 gemaakt\n");
    hSlot3 = CreateFile("\\\\.\\mailslot\\slot3",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    printf("Slot3 gemaakt\n");

    printf("Voor Sleep\n");
    Sleep(1000);
    printf("Na Sleep\n");
    
    // Write to mailslots what you want them to output.
    WriteFile(hSlot1, &toPrint, sizeof(toPrint), &dwWritten, NULL);
    WriteFile(hSlot2, &toPrint, sizeof(toPrint), &dwWritten, NULL);
    WriteFile(hSlot3, &toPrint, sizeof(toPrint), &dwWritten, NULL);

    CloseHandle(hSlot1);
    CloseHandle(hSlot2);
    CloseHandle(hSlot3);
}


En hier de code van het te uitvoeren programma:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <windows.h>

void showChar(char character)
{  
    printf("character= %c \n",&character);  
}

int main(int argc,char * argv[]){   
    
    DWORD dwRead;

    HANDLE hSlot = CreateMailslot(argv[1], 0,  MAILSLOT_WAIT_FOREVER,  NULL);

    printf("Mailslot name: %s\n", argv[1]);
    while (TRUE)
    {
        char buf[32];
        
        ReadFile(hSlot, buf, sizeof(buf), (LPDWORD)&dwRead, NULL);  // Receive message from master.
        showChar(buf[0]);                                       // print what the master has told us to.
    }
    return 0;
}


Wat gebeurt er? Nou teneerste maakt ie geen 3 consoles meer aan. :? Hij maakt alleen een console voor de laatste mailslot, mailslot3 dus...
ten 2e komt het character 'a' niet door, het uit te voeren programma komt wel in de WHILE TRUE terecht, maar met READFILE gebeurt er niets.... Snap niets van... ik had al geprobeerd hier en daar code even te commentariseren om te kijken of ie met 1 wel werkte maar zelfde verhaal. Maar ik dacht dat het zo toch zou moeten werken, tenminste dat die subprogramma op zijn minst de a bleven printen. Synchroniseren komt daarna pas... en daar zie ik nu al tegen op, maar ik blijf volhouden!!
Pagina: 1