|
You last visited: Today at 20:34
Advertisement
CreateProcess Problem
Discussion on CreateProcess Problem within the General Coding forum part of the Coders Den category.
11/28/2009, 21:13
|
#1
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
CreateProcess Problem
PHP Code:
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
TCHAR buf[MAX_PATH];
GetCurrentDirectory(MAX_PATH,buf);
TCHAR path[MAX_PATH] = L"\"";
_tcscat_s(path,buf);
_tcscat_s(path,_T("\\S4Client.exe"));
TCHAR param1[] = L" -rc:eu -lac:eng -auth_server_ip:217.110.102.94\"";
TCHAR param2[] =L" -rc:eu -lac:ger -auth_server_ip:217.110.102.94\"";
TCHAR path2[MAX_PATH];
_tcscpy(path2,path);
_tcscat_s(path,L"\"");
if(lac == 1)
{
_tcscat_s(path2,param1);
if(!CreateProcess(path,path2,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
CString str;
str.Format( L"Error: %i", ::GetLastError());
MessageBox( str, L"Error!", MB_OK );
}
}
else if(lac == 2)
{
_tcscat_s(path2,param2);
if(!CreateProcess(path,path2,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
CString str;
str.Format( L"Error: %i", ::GetLastError());
MessageBox( str, L"Error!", MB_OK );
}
}
else
AfxMessageBox(_T("Keine Sprache gewählt./ No Language selected!"));
AfxMessageBox(path);
AfxMessageBox(path2);
Hab mal den Code zuerst gepostet.
So hi erstmal und zu meinem Problem^^:
Der Folgende Code soll ein kleiner Launcher für das Spiel S4-League werden.
Die Variable lac ist die Wahl der Sprache und bekommt mit 2 Radiobuttons ihren Wert.
Der Client erwartet die Parameter:
-rc: (für uns nur eu)
-lac: (sprache; in meinem launcher nur eng und ger)
-auth_server_ip: (die ip des loginservers die meines wissens für eu gleich ist, wenn nicht, kann ich sie ja noch ändern; das problem tritt schon vorher auf!)
So ich habe schon etliches Probiert! Seit 16 Uhr bin ich am googlen und umschreiben, aber ich kriegs nicht gebacken.
Mal ist der Fehlercode 123 (heißt Fehler in der Aufrufsyntax; verwirrt mich ziemlich, denn wenn ich den ersten Parameter von CreateProcess weglasse, kommt 745 (bin mir jetzt nicht mehr sicher), obwohl bei beiden Möglichkeiten unten von den zwei DebugMessageBoxen der selbe Pfad ausgegeben wird!), mal 2 und eben auch mal 745.
Ich bin echt am Verzweifeln und finde einfach nicht die Lösung.
Der Pfad ist immer richtig [habe es einmal mit absolutem Pfad probiert und einmal mit relativem (beim 1. u. 2. Parameter nur S4Client.exe (beim zweiten noch die Parameter)) und auch einmal halb halb (beim 1. relativ beim 2. absolut)]!
Es will einfach nicht klappen.
Könnte mir einer dabei helfen?
Danke im Voraus Sm!th
|
|
|
11/28/2009, 22:20
|
#2
|
elite*gold: 42
Join Date: Jun 2008
Posts: 5,425
Received Thanks: 1,888
|
|
|
|
11/28/2009, 22:30
|
#3
|
elite*gold: 0
Join Date: Nov 2008
Posts: 161
Received Thanks: 38
|
Nicht wirklich viel Lust bei dir Fehler zu suchen, hier mal meine (funktionierende) Implementierung in C++ :
Code:
ProcessId Process::createProcessAndOpen(const std::wstring& applicationName, const std::wstring& commandlineArguments, bool suspended, DWORD waitingTime)
{
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
ZeroMemory(&siStartupInfo, sizeof(siStartupInfo));
ZeroMemory(&piProcessInfo, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
std::wstring formattedArguments(L"\"" + applicationName + L"\" " + commandlineArguments);
int ec;
if(suspended)
ec = CreateProcessW(applicationName.c_str(), &formattedArguments[0], NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &siStartupInfo, &piProcessInfo);
else
ec = CreateProcessW(applicationName.c_str(), &formattedArguments[0], NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &siStartupInfo, &piProcessInfo);
if(!ec)
throw std::runtime_error("Process::createProcessAndOpen Error : CreateProcessW() failed");
if(waitingTime)
{
if(WaitForSingleObject(piProcessInfo.hThread, waitingTime) == WAIT_FAILED)
throw std::runtime_error("Process::createNewProcess Error : WaitForSingleObject() failed");
}
processId_ = piProcessInfo.dwProcessId;
processHandle_ = piProcessInfo.hProcess;
threadHandle_ = piProcessInfo.hThread;
return processId_;
}
|
|
|
11/28/2009, 22:56
|
#4
|
elite*gold: 150
Join Date: Apr 2007
Posts: 2,394
Received Thanks: 6,644
|
Code:
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
char path[256];
GetCurrentDirectory(256, path);
strcat_s(path, 256, "\\beispiel.exe parameter");
CreateProcess(NULL, path, NULL, NULL, NULL, NULL, NULL, NULL, &si, &pi);
|
|
|
11/28/2009, 23:16
|
#5
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Quote:
Originally Posted by MoepMeep
|
sehr hilfreich
als ob ich da nicht schon gewesen wäre 
danke wurstbrot.
werde mal sehen, dass ich das einbaue
edit:
hm 1. das zweite was du gepostet hast, wird nicht klappen, wegen den parametern (fehlende extra ")
da müsste man dann noch die parameter dranhängen + "" um alles
2. das erste:
eine frage
was bedeutet formattedArguments[0]?
ist das nicht das erste zeichen sprich "? warum genau gibst du das als Argument für Cmdline?
|
|
|
11/28/2009, 23:32
|
#6
|
elite*gold: 0
Join Date: Nov 2008
Posts: 161
Received Thanks: 38
|
Quote:
hm 1. das zweite was du gepostet hast, wird nicht klappen, wegen den parametern (fehlende extra ")
da müsste man dann noch die parameter dranhängen + "" um alles
|
Nein. Programmname in Anführungszeichen, Parameter einfach anhängen
Quote:
2. das erste:
eine frage
was bedeutet formattedArguments[0]?
ist das nicht das erste zeichen sprich "? warum genau gibst du das als Argument für Cmdline?
|
Ein Zeiger auf das erste Zeichen, hätte auch c_str() aufrufen können. Hatte früher das Programm anders strukturiert und ich hab nen std::vector<wchar_t> übergeben, das könnte ich mal ausbessern obwohl es egal ist.
|
|
|
11/28/2009, 23:42
|
#7
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Quote:
Originally Posted by flo8464
Nein. Programmname in Anführungszeichen, Parameter einfach anhängen 
.
|
das hatte ich ja vorher
da kam error 123!
im internet habe ich gelesen, dass man für mehrere parameter "" braucht, damit es klappt
da aber auch generell für die initialisirung "" gebraucht werden braucht man \"
also TCHAR[MAX_PATH] = L"\" name -arg -arg -arg\""
damit herauskommt
"name -arg -arg -arg", was ja gebraucht wird für das starten
ok in der komandozeile braucht man es nicht, aber wie gesagt, ganz am anfang, als ich noch gar nichts mit diesen ganzen \" gemacht habe, hatte ich es so, ohne die anführungszeichen gemacht, wie es wurstbrot als zweites gepostet hat! und das hab nen error
|
|
|
11/29/2009, 02:58
|
#8
|
elite*gold: 0
Join Date: Nov 2008
Posts: 161
Received Thanks: 38
|
Nein, Argumente in Anführungszeichen zu setzen ist einfach falsch.
Du darfst sie auch nicht als Einheit betrachten.
Was arbeitest du eigentlich in deinem C++-Programm mit so vielen Low-Level Strings?
|
|
|
11/29/2009, 10:29
|
#9
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
wieso low?
komisch, also in viele problemberichten sehe ich, dass es probleme gibt (lol), wenn man mehrere parameter hat, die durch leerzeichen getrennt sind, weil es dann nicht funktioniert.
naja ich probiers nochmal.
nö sag ich doch.
gibt error 740
PHP Code:
STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) );
TCHAR buf[MAX_PATH]; GetCurrentDirectory(MAX_PATH,buf); TCHAR path[MAX_PATH] = L""; _tcscat_s(path,buf); _tcscat_s(path,_T("\\S4Client.exe")); TCHAR param1[] = L" -rc:eu -lac:eng -auth_server_ip:217.110.102.94"; TCHAR param2[] =L" -rc:eu -lac:ger -auth_server_ip:217.110.102.94"; TCHAR path2[MAX_PATH]; _tcscpy(path2,path); //_tcscat_s(path,L"\"");
if(lac == 1) { _tcscat_s(path2,param1); if(!CreateProcess(NULL,path2,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) { CString str; str.Format( L"Error: %i", ::GetLastError()); MessageBox( str, L"Error!", MB_OK ); } } else if(lac == 2) { _tcscat_s(path2,param2); if(!CreateProcess(NULL,path2,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) { CString str; str.Format( L"Error: %i", ::GetLastError()); MessageBox( str, L"Error!", MB_OK ); } } else AfxMessageBox(_T("Keine Sprache gewählt./ No Language selected!")); AfxMessageBox(path); AfxMessageBox(path2);
Die MessageBox gibt nun aus:
"F:\S4League\S4Client.exe -rc:eu -lac:ger -auth_server_ip:217.110.102.94" (aber ohne die ""! vorher hat er aus gegeben ""..."" (ohne die äußeren ""^^))#
edit: das gibts doch nicht. ich habe jetzt mal die parameter und damit die leerzeichen weggelassen und es geht immer noch nicht!
error 740
mal schnell googlen
p.s. ein paar auszüge aus anderen foren:
Quote:
Quote:
Hallo , sorry, dass ich den alten Beitrag wieder ausgrabe, aber ich habe ein ähnliches Problem.
D.h. eigentlich funktioniert alles so wie es soll, nur wenn die Übergabeparameter ein Leerzeichen enthalten müste man sie eigentlich in
"" Zeichen setzen. Macht man das, wird aber der Pfad zum Programm nicht mehr erkannt.
D.h. ich kann das Ganze nur nutzen wenn ich Übergabeparameter ohne Leerzeichen verwende. Hat jemand eine Idee wie man das zum Laufen bekommen könnte?
Also ich verwende einen Module Name (Pfad zur CMD.EXE) und in der CommandLine (zweiter Parameter) den Pfad zum Programm, oder zur Batch Datei plus der Startparameter.
|
Quote:
Wenn man Klammern im Pfad hat geht es auch nicht....
"C:/User/New Folder/my.cmd" klappt
"C:/User/New Folder(2)/my.cmd" klappt nicht.
|
|
edit: ahhh 740 ist ein Zugriffsproblem
Launcher mit Adminrechten ausgeführt und es ging.
Komisch nur, dass diese zitierten anderen Probleme mit Leerzeichen haben.. =/
Naja danke auf jeden Fall euch beiden.
edit: noch eine Frage:
Wenn du sagst, diese extra " sind falsch, weil man das nicht darf, warum funktioniert dann wurstbrots Implementierung?
Da sind doch auch L"\"" bei!
ah schon gut...^^ bei Leerzeichen im Pfad, müssen "" nicht bei den Parametern
Ok, alle Fragen geklärt, Launcher fertig und dank wurstbrots Post auch noch eine kleine Extrafunktion eingebaut.
Danke euch beiden^^
|
|
|
11/29/2009, 11:51
|
#10
|
elite*gold: 0
Join Date: Nov 2008
Posts: 161
Received Thanks: 38
|
Sehr schön.
Mit Low-LevelStrings meine ich deine char-Arrays (TCHAR[]).
C++-Strings, also die Strings aus der Standardbibliothek, sind leichter zu bedienen, sicherer und es ist einfach besserer Stil.
Wenn du weiterhin sowohl ASCII als auch Unicodestrings unterstützten möchtest, was ich nichtmal tun würde da ASCII auf Windows eigentlich nichts mehr verloren hat, typedef dir nen Stringtyp zusammen. "typedef basic_string<TCHAR> tstring" oder soetwas. ;>
|
|
|
11/29/2009, 11:58
|
#11
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Nein ich bin da kein Fan von.
Ich mag CString und std::string am liebsten, aber für GetCurrentDirectory hatte ich nunmal nur ein Beispiel mit TCHAR zur Hand und bei CreateProcess konnte als zweiter Parameter CString nicht in LPWSTR konvertiert werden....... und da hatte ich bei so einem kleinen Projekt keine Lust auf großartige Konvertierung.
Normalerweise, wie gesagt nutze ich CString und manchmal auch std::string^^
p.s. Zum Teil auch deswegen, weil ich Arrays noch nie mochte xD
|
|
|
11/29/2009, 12:23
|
#12
|
elite*gold: 0
Join Date: Nov 2008
Posts: 161
Received Thanks: 38
|
Quote:
Originally Posted by MrSm!th
Nein ich bin da kein Fan von.
Ich mag CString und std::string am liebsten, aber für GetCurrentDirectory hatte ich nunmal nur ein Beispiel mit TCHAR zur Hand
|
Code:
std::vector<wchar_t> buffer(MAX_PATH);
GetCurrentDirectoryW(buffer.size(), &buffer[0]);
std::wstring myDirectory(buffer.begin(), buffer.end());
Saubere C++-Lösung.
Quote:
Originally Posted by MrSm!th
p.s. Zum Teil auch deswegen, weil ich Arrays noch nie mochte xD
|
Solltest du auch nicht, wozu etwas statisches wenn es dynamische Containerklassen in C++ gibt
Quote:
|
und bei CreateProcess konnte als zweiter Parameter CString nicht in LPWSTR konvertiert werden
|
Ich gehe mal von den STL-strings aus. LPWSTR ist nichts anders als ein typdef auf wchar_t*. Ein std::wstring gibt beim Aufruf der Memberfunktion c_str() einen solchen Zeiger zurück, allerdings einen konstanten der hier nicht gefragt ist. In diesem Fall solltest du eher einen Zeiger auf das erste Zeichen übergeben:
Code:
std::wstring meinString("foobar");
CreateProcessW(, &meinString[0], ...);
CString ist etwas aus der MFC, oder? Würde ich nicht unbedingt nutzen.
|
|
|
12/15/2009, 22:13
|
#13
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
old post:
Ist aber sehr Praktisch und der Standardtyp von Editboxen
Danke für die zwei Lösungen, werde sie dem nächst mal probieren.
Und nochmals danke euch zwei, ohne euch wär ich nicht weitergekommen xD
Habt auch Credits beim release bekommen
new:
So. Entschuldigung, dass ich diesen etwas älteren Thread wieder hoch holen muss, aber es gibt wieder mal ein kleines Problem mit CreateProcess und ich hoffe ich kann wieder so eine Hilfe wie beim letzten Mal bekommen.
Also:
Wir waren ja so weit, das Spiel zu starten, wenn der Launcher im selben Verzeichnis ist.
So nun bekam ich den Tipp, dass der Hackshield einen Registryeintrag mit seinem Verzeichnis macht.
Also wollte ich dessen Pfad auslesen und dann das HShield durch S4Client.exe ersetzen.
Ging auch super.
Nur gabs nen Error vom Client. Mittlerweile weiß ich warum:
Der Client wird wegen Parameter 8 =NULL im selben Verzeichnis wie der Launcher gestartet.
Das sollte kein Problem sein, wenn er im selben Verzeichnis ist, aber das soll ja gerade keine Bedingung sein.
Also habe ich eben aus dem Pfad den ich sowieso schon ausgelesen habe, auch noch den Pfad nur zum Verzeichnis ohne S4Client.exe ausgelesen.
War ja keine Schwierigkeit.
Da war das Konvertieren in LPCWSTR schon etwas schwerer, ging aber dank ein kleines bisschen C&P auch ohne Probleme.
Nur gibts eine Exception wegen Zugriffsverletzung.
(Und da bei google die meisten Beispiele mit dem Parameter=0 sind, habe ich kein ähnliches Problem+Lösung gefunden!)
Hier mal der nötige Code:
PHP Code:
//Globale Variablen std::string path; int size; // ich weiß nicht elegant, war aber an dem Abend gerade nicht am logischsten und habe auf einen Rückgabewert verzichtet :D
void FindDir() { //Pfad auslesen char buf[256]; HKEY hKey; char temp[256]; DWORD dwType = 0; DWORD dwBufSize = 255; if( RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Ahnlab\\HShield"),0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) { dwType = REG_SZ; if(RegQueryValueEx(hKey,_T(""),NULL, &dwType,(LPBYTE)temp, &dwBufSize)==ERROR_SUCCESS) {
//hier beginnt der Teil zum kopieren ohne die Nullen, die einfach zwischen die Arrayelemente gesetzt werden, zu übernehmen! int i =0; int i2 = 0; while(i <256) { buf[i2] = temp[i]; i2++; i = i+2; } //Ende path = buf; size = strlen(buf)-8; // wurd für das substr() gleich gebraucht und für replace()
} else { CString str; str.Format(L"Error: %i",GetLastError()); AfxMessageBox(str); } RegCloseKey(hKey); } else { CString str; str.Format(L"Error: %i",GetLastError()); MessageBox(str,L"Error!",MB_OK); } }
std::wstring s2ws(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; }
void ClittleS4launcherDlg::OnBnClickedButton1() { ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) );
//Dir + Namen anhängen FindDir(); std::string str1 = "\\S4Client.exe\""; path.replace(size,str1.length(),str1); path = "\""+path; std::string tmp = path.substr(0,size+2);
//Working Dir std::wstring stemp = s2ws(tmp); LPCWSTR dir = stemp.c_str();
//Konvertieren vom vollen Pfad const char* all = path.c_str(); int len = 1 + strlen(all); wchar_t* t = new wchar_t[len]; mbstowcs(t, all, len); TCHAR* path2 = (TCHAR*)t;
TCHAR param1[] =L" -rc:eu -lac:eng -auth_server_ip:217.110.102.94"; TCHAR param2[] =L" -rc:eu -lac:ger -auth_server_ip:217.110.102.94";
if(lac == 1) //Englisch { _tcscat(path2,param1); if(!CreateProcess(NULL,path2,NULL,NULL,FALSE,0,NULL,dir,&si,&pi)) { CString str; str.Format( L"Error: %i", ::GetLastError()); MessageBox( str, L"Error!", MB_OK ); } } else if(lac == 2) //Deutsch { _tcscat(path2,param1); if(!CreateProcess(NULL,path2,NULL,NULL,FALSE,0,NULL,dir,&si,&pi)) { CString str; str.Format( L"Error: %i", ::GetLastError()); MessageBox( str, L"Error!", MB_OK ); } } else AfxMessageBox(_T("Keine Sprache gewählt./ No Language selected!"));
} }
|
|
|
12/15/2009, 22:26
|
#14
|
elite*gold: 0
Join Date: Sep 2006
Posts: 248
Received Thanks: 110
|
Quote:
Originally Posted by MrSm!th
...
|
In deiner OnBnClickedButton1 funktion entsteht ein Memory leak. Da fehlt ein delete[] t; und denk dir mal bessere namen für die Variablen aus. Les mir mal den code in paar minuten durch.
|
|
|
12/15/2009, 22:29
|
#15
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
hm.
und alleine deswegen?
der fehler kommt erst bei CreateProcess
(und solche mini-namen nehme ich gerne für Variablen die kruzzeitig genutzt werden/rückgabewerte sind (außerdem ist gerade der teil C&Ped; ich habe nach einer guten Konvertierungsmöglichkeit gesucht und das gefunden^^) für wichtige nehme ich auch welche mit sinn)
edit: Ausnahme kommt immernoch.
Ich vermute, dass es an einem Overflow liegt, der durch Nutzen von _tcscpy anstatt _tcscpy_s kommt. Aber eigentlich habe ich dafür gesorgt, dass alles passen müsste und beim Debuggen werde alle String (auch nach _tcscpy) richtig angezeigt =/
|
|
|
Similar Threads
|
Metin 2 Pserver Problem/ Lösung für das Matrix Kartennummer Problem
01/04/2010 - Metin2 Private Server - 3 Replies
Hy Leute
Wie in der Überschrift genannt, hab ich gerade ein Problem mit meinem Metin 2Server.
Ich lasse ihn via Loopbackadapter laufen, funktioniert auch ganz gut.
Ich hab aber jetzt das Poblem, das in meinem Account nur noch Krieger mit Level null stehen.
Wie kann ich das Beheben??, das is auch manchmal da, wenn ich via Navicat n neuen Account mach. Hoffe einer hatt ne Lösung
Hab n Screenshot im Anhang
Aber ich hab ja auch ne Lösung für n anderes Problem.
Gestern hatte ich beim...
|
[Problem] Problem with server starting - cannot find quest index for PaxHeader
12/22/2009 - Metin2 Private Server - 1 Replies
Hello!
I have this same problem as here when i'm starting my server:
http://www.elitepvpers.com/forum/metin2-pserver-di scussions-questions/307143-metin2-serverfiles-ques t-index-fehler.html
But I didn't know the answer.. how to repair this?
Greetings
|
All times are GMT +1. The time now is 20:35.
|
|