PDA

View Full Version : ارسال پارامتر به فایل vb



ghaum
سه شنبه 20 مرداد 1383, 09:38 صبح
سلام

فرض کنید که یک برنامه با vb نوشتید که برای اجرا شدن نیاز به پارامتر دارد

بعد بخواهید آن را از طریق خط فرمان اجرا کنید
آیا امکانش هست؟
مثل دستور Format

متشکرم

روانشناس
سه شنبه 20 مرداد 1383, 13:51 عصر
بله می تونید از Command در VB استفاده کنید. اگر پارامتری به برنامه شما ارسال شود با استفاده از Command به آن دسترسی دارید.

ghaum
چهارشنبه 21 مرداد 1383, 07:21 صبح
سلام
خیلی متشکرم

چطور می توانم از command در vb استفاده کنم؟

AminSobati
پنج شنبه 22 مرداد 1383, 00:37 صبح
دوست عزیزم،
اگر استفاده از Array براتون راحته، میتونید یکباره محتویات Command رو با استفاده از تابع Split به Array تبدیل کنین. با فرض به اینکه کاربر برنامه شما از اسلش (/) برای جدا کردن پارامترها استفاده میکنه و برنامه در VB6 نوشته میشه(چون تابع Split در VB5 وجود نداره)، این کار رو میتونید انجام بدین:


Private Sub Form_Load()
Dim MyArray() As String, i As Integer
MyArray = Split(Command, "/")
For i = 1 To UBound(MyArray)
MsgBox MyArray(i)
Next i
End Sub


حالا برنامه رو مثلا به اسم MyApp.exe کامپایل میکنیم. اگر کاربر به این شکل برنامه رو اجرا کنه، تک تک پارامترها نمایش داده میشن:



MyApp.exe /Param1 /Param2

ali2914
پنج شنبه 22 مرداد 1383, 06:24 صبح
:تشویق: خیلی خوب این مشکل منم بود از هر دوتون ممنون

AminSobati
پنج شنبه 22 مرداد 1383, 10:55 صبح
:)

ghaum
شنبه 24 مرداد 1383, 08:05 صبح
خیلی متشکرم از راهنماییتان

موفق باشید

AminSobati
شنبه 24 مرداد 1383, 08:47 صبح
خواهش میکنم :)

MM_Mofidi
دوشنبه 26 مرداد 1383, 10:51 صبح
آیا کسی برای برگرداندن پارامتر هم راهی دارد؟

AminSobati
دوشنبه 26 مرداد 1383, 11:34 صبح
دوست عزیز،
برگرداندن پارامتر از کجا به کجا منظورتونه؟

MM_Mofidi
سه شنبه 27 مرداد 1383, 19:07 عصر
یعنی به فرض برنامه EXE نوشته شده با vb توسط یک برنامه دیگر اجرا میشود.نتایج حاصله چگونه به برنامه قبلی پاس شود؟(بدون استفاده از فایل واسط)

AminSobati
چهارشنبه 28 مرداد 1383, 22:29 عصر
اگر شما بدون هیچ واسطه ای قصد انجام این کار رو دارید، در اصل 2 تابع API به نامهای ExitProcess و GetExitCodeProcess با همکاری با چند API دیگه برای این منظور استفاده میشن ولی کاربردشون چندان سرراست نیست.
SaveSetting و GetSetting که از توابع خود VB هستن در بسیاری از موارد برای انجام این کار کاملا جوابگو هستند.
موفق باشید،
امین ثباتی

MM_Mofidi
پنج شنبه 29 مرداد 1383, 16:02 عصر
AminSobati عزیز استفاده از مواردی را که فرمودید به اضافه روشهای مشابه با استفاده از فایل یا پارامتر واسط را بلدم.
مشکلم برای استفاده از این EXE در جایی است که برنامه مادر این قابلیتهارا به من نمیدهد.
در c تا جایی که من میدانم( اساتید اصلاح بفرمایند) حتی خود تابع Main میتوانست لااقل 0 یا 1 را به معنی صحت یا عدم صحت اجرا برگرداند.
روش مشابه در VB نداریم?????
همانطور که همه Function ها را میتوانیم (برای برگرداندن خروجی) برابر یک عدد قرار دهیم؟؟؟

AminSobati
پنج شنبه 29 مرداد 1383, 23:10 عصر
دوست عزیزم،
متاسفانه در VB روشی به اون سرراستی که در C اشاره کردین نداریم(برای برگرداندن مقدار). ولی برنامه ای که قراره مقدار رو برگردونه، اگر سورسش دست شما نیست، شاید خود برنامه نویسش این فکر رو کرده باشه که بسته به شرایط خروج از برنامه، یک مقدار رو برای نتیجه set کنه که شما توسط همون API در برنامه VB بدست میاریدش. اگر چنین کاری نکرده باشه متاسفانه از دست من و شما کاری ساخته نیست!

موفق باشید

MM_Mofidi
جمعه 30 مرداد 1383, 15:05 عصر
توابعی که اشاره فرمودید در MSDN دیدم گفتهاول GetExitCodeProcess را استفاده کنید تا Pointer to a variable to receive the process termination status.
را به شما بدهد که پاس کنید به ExitProcess تا پروسس را پایان دهد ولی تابع خروجی برنمیگرداند که


VOID ExitProcess(
UINT uExitCode // exit code for all threads
);

اگه مثالی دارید ممنون میشم یا لا اقل یه توضیح که چگونه باید عمل مورد نظر را(برگرداندن مقدار به سیستم هنگام خروج)انجام داد؟

SalarSoft
جمعه 30 مرداد 1383, 17:06 عصر
با اجازه. :)

با استفاده از کد زیر می توانید پارامتر های مانند زیر را از هم تشخیص دهید:


c:\myexe.exe "hello world" "how are you today?"


Public Function ParamStr(fIndex As Integer) As String
On Error Resume Next
Dim fParam As String
Dim fPrm As String
Dim fParams As New Collection
Dim Index As Integer
Dim Count As Integer
fParam = VBA.Command
If fParam = "" Then Exit Function
Index = 1
ParamStr = ""
Count = 0
Do While True
Do While VBA.Mid(fParam, Index, 1) <> " "
If Index > Len(fParam) Then Exit Do
If VBA.Mid(fParam, Index, 1) = VBA.Chr(34) Then ' Vba.chr(34)= "
Index = Index + 1
fPrm = fPrm + VBA.Mid(fParam, Index, 1)
Index = Index + 1
Do While VBA.Mid(fParam, Index, 1) <> VBA.Chr(34)
fPrm = fPrm + VBA.Mid(fParam, Index, 1)
Index = Index + 1
Loop
Exit Do
End If
If VBA.Mid(fParam, Index, 1) <> " " Then
fPrm = fPrm + VBA.Mid(fParam, Index, 1)
End If
Index = Index + 1
Loop
If Index > Len(fParam) Then Exit Do
fParams.Add (fPrm)
fPrm = ""
Count = Count + 1
Index = Index + 1
Loop
ParamStr = fParams.Item(fIndex)
End Function

مثلا برای مثال بالا
ParamStr(1) برابر خواهد بود با hello world

AminSobati
جمعه 30 مرداد 1383, 20:13 عصر
دوست عزیزم،
در این آدرس یک مثال کوچیک وجود داره:
http://www.mentalis.org/apilist/ExitProcess.shtml
در این آدرس اگر چه بحث چیزه دیگه ای هستش، ولی از GetExitCodeProcess استفاده کرده و کار جالبیه:
http://www.google.com/groups?selm=uJnLo28OEHA.1620%40TK2MSFTNGP12.phx.gb l&output=gplain
ضمنا به طور اتفاقی در MSDN با این مثال برخورد کردم، ولی چون با زبان C چندان آشنا نیستم، نمیدونم چقدر به خواسته شما نزدیکه، ولی دیدنش ضرر نداره:


Platform SDK: DLLs, Processes, and Threads
Creating a Child Process with Redirected Input and Output

The example in this topic demonstrates how to create a child process from a console process. It also demonstrates a technique for using anonymous pipes to redirect the child process's standard input and output handles. Note that named pipes can also be used to redirect process I/O.


The CreatePipe function uses the SECURITY_ATTRIBUTES structure to create inheritable handles to the read and write ends of two pipes. The read end of one pipe serves as standard input for the child process, and the write end of the other pipe is the standard output for the child process. These pipe handles are specified in the SetStdHandle function, which makes them the standard handles inherited by the child process. After the child process is created, SetStdHandle is used again to restore the original standard handles for the parent process.

The parent process uses the other ends of the pipes to write to the child process's input and read the child process's output. The handles to these ends of the pipe are also inheritable. However, the handle must not be inherited. Before creating the child process, the parent process must use DuplicateHandle to create a duplicate of the application-defined hChildStdinWr global variable that cannot be inherited. It then uses CloseHandle to close the inheritable handle. For more information, see Pipes.

The following is the parent process.

#include <stdio.h>
#include <windows.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);

DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;

// Set the bInheritHandle flag so pipe handles are inherited.

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;

// The steps for redirecting child process's STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.

// Save the handle to the current STDOUT.

hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process's STDOUT.

if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");

// Set a write handle to the pipe to be STDOUT.

if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit("Redirecting STDOUT failed");

// Create noninheritable read handle and close the inheritable read
// handle.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd);

// The steps for redirecting child process's STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.

// Save the handle to the current STDIN.

hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

// Create a pipe for the child process's STDIN.

if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");

// Set a read handle to the pipe to be STDIN.

if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
ErrorExit("Redirecting Stdin failed");

// Duplicate the write handle to the pipe so it is not inherited.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");

CloseHandle(hChildStdinWr);

// Now create the child process.

if (! CreateChildProcess())
ErrorExit("Create process failed");

// After process creation, restore the saved STDIN and STDOUT.

if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
ErrorExit("Re-redirecting Stdin failed\n");

if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
ErrorExit("Re-redirecting Stdout failed\n");

// Get a handle to the parent's input file.

if (argc > 1)
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
else
hInputFile = hSaveStdin;

if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("no input file\n");

// Write to pipe that is the standard input for a child process.

WriteToPipe();

// Read from pipe that is the standard output for child process.

ReadFromPipe();

return 0;
}

BOOL CreateChildProcess()
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

// Set up members of the PROCESS_INFORMATION structure.

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure.

ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);

// Create the child process.

return CreateProcess(NULL,
"child", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
}

VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL)) break;
}

// Close the pipe handle so the child process stops reading.

if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed\n");
}

VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Close the write end of the pipe before reading from the
// read end of the pipe.

if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");

// Read output from the child process, and write to parent's STDOUT.

for (;;)
{
if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
break;
}
}

VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}

// The code for the child process.

#include <windows.h>
#define BUFSIZE 4096

VOID main(VOID)
{
CHAR chBuf[BUFSIZE];
DWORD dwRead, dwWritten;
HANDLE hStdin, hStdout;
BOOL fSuccess;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if ((hStdout == INVALID_HANDLE_VALUE) ||
(hStdin == INVALID_HANDLE_VALUE))
ExitProcess(1);

for (;;)
{
// Read from standard input.
fSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
if (! fSuccess || dwRead == 0)
break;

// Write to standard output.
fSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
if (! fSuccess)
break;
}
}


امیدوارم اینها بتونه کمکتون کنه.
موفق باشین
امین ثباتی

MM_Mofidi
شنبه 31 مرداد 1383, 10:43 صبح
هردو مثال شما را دیدم جالب بود اما مشکل را حل نکرد.
اولی Proccess فعال را میگیرد باکمک هندلش آن را Kill میکند.(برگرداندن پارامتر؟؟؟؟؟)
مثال دومی هم روش خواندن مقدار پاس شده از یک فایل اجرایی را توسط تابعGetExitCodeProcess بیان میکند
نه نحوه بازگرداندن کد از یک برنامه اجرایی به برنامه مادر را

AminSobati
شنبه 31 مرداد 1383, 19:13 عصر
جسارتا اگر به لینک دوم دقت بفرمایید، lExitCode در GetExitCodeProcess مقدار برگشتی رو بدست میاره. من به این مثال یک textbox و یک button اضافه میکنم و کد رو به این شکل مینویسم:


Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const STILL_ACTIVE = 259
Private Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" ( _
ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Private Function Process_Shell(Pathname As String, _
Optional WindowStyle As VbAppWinStyle = vbMinimizedFocus) As Long
Dim ProcID As Long
ProcID = Shell(Pathname, WindowStyle)
Process_Shell = OpenProcess(PROCESS_QUERY_INFORMATION, True, _
ProcID)
End Function
Private Sub Command1_Click()
Dim lExitCode As Long
Call GetExitCodeProcess(Val(Text1.Text), lExitCode)
If lExitCode = STILL_ACTIVE Then
MsgBox "The app is still open!"
Else
MsgBox "The app was terminated with return value: " & lExitCode
End If
End Sub
Private Sub Form_Load()
Text1.Text = Process_Shell("C:\MyApp.exe")
End Sub
Private Sub Form_Unload(Cancel As Integer)
CloseHandle Val(Text1.Text)
End Sub

تنها کاری که لازمه انجام بدین، ساختن MyApp.exe هستش که با ExitProcess به کارش خاتمه میده:


Private Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
Private Sub Command1_Click()
ExitProcess 1234
End Sub

تا زمانی که MyApp.exe در حال اجرا هست، Command1_Click در برنامه اول پیغام میده که هنوز برنامه بازه. ولی اگر در برنامه دوم(MyApp.exe) بوسیله ExitProcess کار رو به پایان ببرین، Command1_Click در برنامه اول مقدار برگشتی رو نمایش میده.

MM_Mofidi
شنبه 31 مرداد 1383, 19:58 عصر
حق با شماست دقیق می فرمایید
من اشتباه کردم
یا بعلت ضعف زبان انگلیسی یا بیدقتی یا عدم بیان مناسب مطلب در مثالها
به هر حال خیلی ممنونم

AminSobati
شنبه 31 مرداد 1383, 21:45 عصر
موفق باشی دوست عزیزم :)

h_shirazee
یک شنبه 25 اردیبهشت 1384, 14:41 عصر
بابا دمتون گرم خیلی با حال بود

mehdiadeli
شنبه 18 مهر 1388, 04:46 صبح
سلام
لطفا به من کمک کنید .

فرض کنید من یک برنامه درست کردم که وقتی بهش پارامتر میدم (myapp.exe test1) اونو تو listbox میریزه
listbox.add Command

حالا برنامه ای که نوشتم اجرا شده و در listbox پارامتر که بهش داده بودم را add کرده
حالا فرض کنید که این برنامه نباید بسته شود برنامه باز مونده و مجدد میخوام بهش پارامتر بدم
(app.exe test2)

وقتی که این کار رو انجام میدم برنامه من دوباره اجرا میشه و پارامتر داخل لیست اضافه میشه
ولی من میخوام تو همون برنامه قبلی که باز هستش تو لیستش اضافه بشه نه برنامه ای دیگه مجدد باز بشه.

لطفا بهم بگید چگونه میتونم بار ها پارامتر رو به یک برنامه باز شده بدم و فقط تو یک لیست اضافه بشه

xxxxx_xxxxx
شنبه 18 مهر 1388, 18:41 عصر
شما باید app.PrevInstance را در زمان لود برنامه چک کنید . اگر True بود یعنی قبلاً اجرا شده. حالا که برنامه در حال اجراست باید برای ارسال پارامتر به اون Handle ش رو پیدا کنید. (با تابع FindWindow) بعد Handle لیست باکس رو پیدا کنید و با SendMessage بهش پارامتر رو ارسال کنید. تقریباً کار مشکلی هست. و بعد هم در آخر باید End کنید یعنی برنامه دوم بسته شه.

mehdiadeli
یک شنبه 19 مهر 1388, 00:11 صبح
از این که کمکم کردید ممنونم .

مشکلم برطرف شد .