PDA

View Full Version : CreateProcess() و مشکل کوتیشن در آرگومان ها



_test_
شنبه 28 مرداد 1391, 02:31 صبح
سلام

یه برنامه دارم که اینجوری میخوام اجراش کنم :

a.exe "arg"ument1" "argument2"

یعنی یه کوتیشن بین 2تا کوتیشنی که دوره آرگیومنت 1 هست باید باشه و کوتیشن جزء ورودی آرگومان1 هست و باید تو تابع CreateProcess() صدا زده شه ..

ممنون میشم راهنماییم کنید .

#target
شنبه 28 مرداد 1391, 02:50 صبح
\" میاد کوتشن میفرسته
a.exe "arg\"ument1" "argument2"

_test_
شنبه 28 مرداد 1391, 02:55 صبح
اینو میدونم دوست من ..
گفتم باید تو CreateProcess بره ..
یعنی یه جفت کوتیشنم دوره کل جمله میره که باز تو گذاشتنش مشکلی نیست , آرگومانا بهم میریزه ..

#target
شنبه 28 مرداد 1391, 03:02 صبح
شاید اینطور منظورته
CreateProcess("a.exe" , "\"arg\"ument1\" \"argument2\"" , ....

_test_
شنبه 28 مرداد 1391, 13:50 عصر
آره مشکلم همینجاست دقیقا ..

یه برنامه هست به اسم a.exe:

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

printf("%s\n%s\n%s\n%s\n%s\n", argv[0], argv[1], argv[2], argv[3], argv[4]);
getch();
return 0;
}


که آرگومان هارو نشون میده.

برنامه اصلی هست :

#include <windows.h>
STARTUPINFO si;
PROCESS_INFORMATION pi;

int main (int argc, char *argv[]){
CreateProcess( ".\\a.exe","\"a\" \"b\" \"c\" \"d\" \"d:\\r.txt\"",NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi );

return 0;
}

الان آرگومان ها توش کوتیشن نداره و وقتی برنامه اصلی رو اجرا میکنی, a.exe رو باز میکنه و اونم

a
b
c
d
d:\r.txt

رو نشون میده ..

حالا اینجوری اگه برنامه اصلی رو تغییر بدیم:

#include <windows.h>
STARTUPINFO si;
PROCESS_INFORMATION pi;

int main (int argc, char *argv[]){
CreateProcess( ".\\a.exe","\"a\"\" \"b\" \"c\" \"d\" \"d:\\r.txt\"",NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi );

return 0;
}

برنامه از کار میفته و اصلا اجرا نمیشه .

بعد که اینجوریش کنیم:


#include <windows.h>
STARTUPINFO si;
PROCESS_INFORMATION pi;

int main (int argc, char *argv[]){
CreateProcess( ".\\a.exe","\"a\"\"\" \"b\" \"c\" \"d\" \"d:\\r.txt\"",NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi );

return 0;
}

برنامه باز میشه ولی خروجی مثل خروجی اوله و باز هم کوتیشنی نیست .

چه کار باید کرد ؟ :(

_test_
شنبه 28 مرداد 1391, 14:28 عصر
اینم اضافه کنم :

D:\>a.exe "1"" 2 3 4
a.exe
1"
2
3
4

درست !

و اگر:

D:\>a.exe "1""" 2 3 4


همون اتفاقی که قبل می افتاد...برنامه اجرا نمیشه اصلا ... فک کنم به این حالت میگن Access Violation ...

_test_
شنبه 28 مرداد 1391, 15:01 عصر
*** حل نشد (آپدیت شد)


#include <windows.h>
#include <string.h>
STARTUPINFO si;
PROCESS_INFORMATION pi;
int main (int argc, char *argv[]){

char p[50];
strcpy(p, getenv("windir"));
strcat(p, "\\system32\\cmd.exe");

CreateProcess( p,"/c .\\a.exe \"a\"\" \"b\" \"c\" \"d\" \"d:\\r.txt\"",NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi );

return 0;
}



* اجرا با خود کنسول command prompt..

_test_
شنبه 28 مرداد 1391, 17:21 عصر
حل نشده کامل :(

رشته ی اصلی قراره این باشه .

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

* اولش با کاراکتر SPACE شروع میشه ..

با بقیه چیکار کنم ؟
برنامه قاطی کرد کلا وقتی بش دادم اینو ... میگفت ورودی کم است ..
انگار از یه جایی به بعد رو حساب نمیکرد :(

_test_
شنبه 28 مرداد 1391, 18:13 عصر
این کاراکتر هارو که حذف میکنم خروجی درسته ولی من به اینام احتیاج دارم:

"&'()<>\^|

که برا کوتیشن جای یکی سه تا بزارم خروجی درست میشه بقیه چی ؟ :)
کسی نیست اینجا به من جواب بده ؟

amin1softco
شنبه 28 مرداد 1391, 19:03 عصر
ببین این به کارت نمی آد :
http://www.goffconcepts.com/techarticles/development/cpp/createprocess.html
تست کردم با گوتیشن مورد داره
http://barnamenevis.org/http://photo.cer33.com/pic/44182379bf9f.jpghttp://photo.cer33.com/pic/44182379bf9f.jpg
ExecuteProcess(L"G:\\a.exe",L"x:1 x:3 y:2 z:\"&'()<>\^|",100);

اینم فک کنم به خاطر تبدیل شدن به رشته سی است...

_test_
یک شنبه 29 مرداد 1391, 00:23 صبح
این تابع شما مشکل اسپیس و کوتیشن داره ...

نتیجه این شده تا الان که دیگه تو استفاده ی کاراکتر های خاص مثل (" ' | > < ..... ) مشکلی ندارم (http://www.robvanderwoude.com/escapechars.php)..

ولی وقتی عین اون جمله ای که تو cmd دستی روی a.exe تست میکنم و جواب میده رو میارم تو محیط برنامه نویسی...خروجی درست نیست .
مثلا دستی تو cmd مینویسم :

D:\>cmd.exe /c "a.exe "^!\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^^_^`abcdefghi
jklmnopqrstuvwxyz{^|}~" "s" "e" "m" "l""

جواب میده بم :

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
s
e
m
l

این یعنی کاملا صحیح .

وقتی میبرمش تو کد c++ :

#include <windows.h>
#include <string.h>

STARTUPINFO si;
PROCESS_INFORMATION pi;
int main (int argc, char *argv[]){

char p[50];
strcpy(p, getenv("windir"));
strcat(p, "\\system32\\cmd.exe");

CreateProcess( p,"/c \".\\a.exe \"^!\\\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~\" \"s\" \"e\" \"m\" \"l\"\"",NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi );

getch();
return 0;
}


برنامه سریع بسته میشه .. انگار یه مسیجی از طرف cmd.exe بیاد و بره ..
* به بعد علامت تعجب تو تابع CreateProcess نگاه کنید که برای ساخت \" , \\\" نوشتم ...

اینم از آخرین وضعیت ..

amin1softco
یک شنبه 29 مرداد 1391, 10:11 صبح
ببین عزیزم این برنامه که گذاشتم هیچ مشکلی نداره یکمی دایکیومت های مایکروسافت رو مطالعه کردم !!!
شما این برنامه رو تست کن با سورسی که قرار دادم نتیجه یکی می شه .

ExecuteProcess(L"G:\\a.exe",L"g:\\a.exe \"^!\\\"\"\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~\" \"s\" \"e\" \"m\" \"l\"",100);


یا این برنامه رو اجرا کن :

#include <Windows.h>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
std::string command = "cmd.exe /c \"g:\\a.exe \"^!\\\"\"\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~\" \"s\" \"e\" \"m\" \"l\"\"";
system(command.c_str());
return 0;
}

http://pic.neru9.com/pic/f42b03a06a1b.jpg
قانونش اینجوریه که باید اول \ ها را با \\ عوض کنی
گوتیشن هایی که برای حفظ اسپیس عبارت است با یک "\ و کوتیشن هایی که باید چاپ بشه با سه تاعوض بشه "\"\"\
که می تونی یک تابع براش بنویسی و خیلی ساده هر کامندی به صورت اتومات درست بشه...
http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.71%29.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
http://www.hardtoc.com/archives/162

_test_
یک شنبه 29 مرداد 1391, 11:16 صبح
خیلی ممنون که دنبال کارم بودی .
system() ترد جدید باز نمیکنه و تو همون ترد برنامه میاد برنامه رو باز میکنه که باعث میشه واسته رو خط system() و به خط های بعد نره ... ممنون ایده ی خوبی بود ولی برای کار من مناسب نیست .

دیشب هم بهت گفتم این قوانین برای کنسول نیست برا کامند پرامته , باید برنامه با cmd.exe /c باز شه ..
خروجی تابع اولی که گذاشتی :


argv[2] = ^!""#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~

اگه از 2تا کوتیشن هم صرف نظر کنیم میبینید ^ های زیادی هستند اینجا که نباید باشن ... شاید با یکم تغییر درست شن .. ممنون .

دیشب خودم فهمیدم اشتباه مسخرم چی بود .. ;))
arg[3] رو نگاه کنید که توش e رو گذاشتیم ..
من طبق روال درست کارم توش >>>> گذاشته بودم و اصلا اشکال تو آرگومان 1 نبود ;))
اینو هم با این تغییر فهمیدم :


CreateProcess( p,"/c \".\\a.exe \" ^!\\\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~\" \"s\" \"e\" \"m\" \"l\"\"",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi );


یعنی تو آخر تابع CREATE_NEW_CONSOLE رو با 0 عوض کردم و اون ارروری که گفتم سریع میاد میره و از طرف cmd هست رو تو برنامم دیدم که گفته بود >> was unexpected فک کنم ..
و کارم درست شد با همین createprocess .

ممنون از همگی

#target
یک شنبه 29 مرداد 1391, 17:27 عصر
هدف فقط اینه که ی سری اطلاعات رو پاش بدی به ی پروسه دیگه ؟ چرا تو ی بخش اشتراکی حافظه نمیذاری ؟ بعد پروسه جدید بره از اونجا اطلاعات رو بخونه

amin1softco
سه شنبه 31 مرداد 1391, 13:19 عصر
هدف فقط اینه که ی سری اطلاعات رو پاش بدی به ی پروسه دیگه ؟ چرا تو ی بخش اشتراکی حافظه نمیذاری ؟ بعد پروسه جدید بره از اونجا اطلاعات رو بخونه

خوب شما همین مثال رو با حافظه اشتراکی حل کن ببینیم ما یاد بگیریم دیگه :دی

#target
سه شنبه 31 مرداد 1391, 14:10 عصر
چشم .
پروسه اصلی اون بافر رو داخل حافظه قرار میده چیزی مثل این
#include <Windows.h>
#include <stdlib.h>
int main()
{

int bsize = 111;
char* Buffer = "^!\"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~";
HANDLE memhandlle = CreateFileMapping(INVALID_HANDLE_VALUE , NULL, PAGE_READWRITE , 0, bsize, L"Global\\MyMem1");
void *data = MapViewOfFile(memhandlle, FILE_MAP_WRITE | FILE_MAP_READ , 0, 0, bsize);
memcpy (data,(void*)Buffer,bsize);

system("C:\\Prc1.exe");

}

بعد پروسه دوم که قراره اینو بخونه میاد اونو باز میکنه و میخونه !
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
int filesize = 111;

HANDLE memhandlle = OpenFileMapping(FILE_MAP_ALL_ACCESS , FALSE , L"Global\\MyMem1");
void *data = MapViewOfFile(memhandlle, FILE_MAP_WRITE | FILE_MAP_READ , 0, 0, filesize);

cout << (char*)data;
}

هندل ها رو در آخر میشه بست

amin1softco
سه شنبه 31 مرداد 1391, 16:29 عصر
ممنون دوست عزیز این روش مثل اینه که محتویات را داخل یک فایل بریزیم و ازش در یک برنامه دیگه بخونیم ولی مشکل اصلی اینه که این دوستمون می خواهد چندتا بچ فایل رو با هم اجرا کنه یا کاری شبیه این و گرنه با همون بچ فایل می شه این کپی در فایل و خواندن از اون رو انجام داد منتها کارکتر های | پایپ > و < و ^ جزو کارکتر های خاص در داس محسوب می شوند که با گذاشتن ^ مشکل حل شده :

@echo off
REM orginal command is dir /p | find "Lo"
echo /p ^| find ^"Lo^" > tfile

REM append this line after first
echo ^!^"#$%^&^'^(^)*+^,-./0123456789:^;^<^=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^^_^`abcdefghijklmnopqrstuvwxyz{^|}~ >> tfile

REM read first line to myvar
Set /P mvar=<tfile

REM run Command
dir %mvar%

PAUSE


ولی این دوستمون فک کنم خبر نداشته که در همون بچ فایل ها می شه از خاصیت چند نخی (http://caseelse.net/2008/05/22/multithreading-in-batch-script-part-1-an-example/) استفاده کرد و زیاد احتیاجی به سی نداره که اینقدر بخواهد دردسر بکشه :دی چون خوده سی هم یکسری کارکتر هایی داره که باید برای رشته اصلاح بشه داس هم یکسری رشته داره که اینا رو حل کرده بعدش مشکل از فراخوانی CreateProcess بود که حل شده.

حالا اگر بشه برای cmd از این حافظه مشترک استفاده کرد خیلی خوبه .