Форум: "Сети";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
Вниз
Перенаправленный ввод-вывод Найти похожие ветки
← →
GanibalLector © (2006-01-17 02:36) [0]Создаю сокет,перенаправляю ввод-вывод на cmd.exe. Захожу клиентом и юзаю cmd.exe из клиента. Так вот,проверяю сие творение на 2 компьютерах. На обном все Ок,а на втором cmd сразу закрывается. В чем может быть дело???
Открыват cmd.exe так :
sHandle := accept(FSocket, nil, nil);
if sHandle <> INVALID_SOCKET then
begin
ZeroMemory(@St, SizeOf(TStartupInfo));
St.cb := SizeOf(TStartupInfo);
St.wShowWindow := SW_SHOW;
St.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
St.hStdInput := sHandle;
St.hStdOutput := sHandle;
St.hStdError := sHandle;
CreateProcess(nil, "cmd.exe", nil, nil, true, 0, nil, nil, St, Pr);
← →
Digitman © (2006-01-17 08:46) [1]Из приведенного фрагмента кода нельзя сделать никаких предположений.
Главное (обмен с cmd) осталось за кадром.
Кр.того, почему нет анализа результата вызова CreateProcess ?
← →
GanibalLector © (2006-01-17 19:56) [2]2 Digitman
> почему нет анализа результата вызова CreateProcess
ф-ция выполнена успешно.
← →
PAVIA © (2006-01-17 22:06) [3]GanibalLector
Какая ОС на компьютерах? А то для этого должна быть поддержка winsock 2.0 или 2.2
← →
GanibalLector © (2006-01-18 01:44) [4]2 PAVIA © (17.01.06 22:06) [3]
На одном XP SP2 - не работает.
На втором XP Sp1 - работает.
2 Digitman © (17.01.06 08:46) [1]
>Главное (обмен с cmd) осталось за кадром.
Не понял. Я могу в принципе и клиента своего выслать.Но ИМХО не стоит. Ибо любой сканер портов заменит моего клиента. Т.е. cmd.exe запустится,а в сканер портов скажет,что мол :Microsoft Windows XP и т.д.
← →
Digitman © (2006-01-18 08:36) [5]Причем здесь конкретная функциональность твоего приложения ?
И причем здесь "сканеры" ?
Ты пытаешься управлять вводом-выводом некоего консольного приложения (в дан.случае - cmd.exe) посредством программных каналов. Вот я и хочу выяснить , какие конкретно данные и как ты посылаешь в канал ввода консоли ..
← →
GanibalLector © (2006-01-18 13:33) [6]2 Digitman
Да,конечно.Вот клиент(черновой вариант!!!пока без синхронизации) :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Start: TButton;
Stop: TButton;
Label1: TLabel;
Edit1: TEdit;
Exec_Console: TButton;
procedure StopClick(Sender: TObject);
procedure StartClick(Sender: TObject);
procedure Exec_ConsoleClick(Sender: TObject);
private
B:Boolean;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
StopThread,WrCons:Boolean;
const MAX_PACKET_SIZE = $10000;
implementation
uses WinSock;
{$R *.dfm}
function Dos2Win(const aStr: String): String;
begin
Result := aStr;
if Result <> "" then
OemToChar(PChar(Result),PChar(Result));
end;
function Win2Dos(const aStr: String): String;
begin
Result := aStr;
if Result <> "" then
CharToOem(PChar(Result),PChar(Result));
end;
procedure Send_(Socket:TSocket;Data:String);
begin
Data:=Win2Dos(Data);
Send(Socket,Data[1],Length(Data),0);
end;
function Recv_(Socket:TSocket; var Data:String):Boolean;
var Len,II:Integer;
Packet: array[0..MAX_PACKET_SIZE - 1] of Byte;
begin
Data:="";
Len:=Recv(Socket,Packet,MAX_PACKET_SIZE,0);
if Len>0 then
begin
for II:=0 to Len-1 do
Data:=Data+Chr(Packet[II]); // от Лукавого.надо будет переделать
Data:=Dos2Win(Data);
Result:=True;
end else Result:=False;
end;
function potok(Param:Pointer):DWord;
var
Sock:TSocket;
Addr:TSockAddr;
Data_:TWSAData;
Data:String;
FDSet:TFDSet;
Tm:TTimeVal;
ServStoped:Boolean;
begin
StopThread:=True;
WrCons:=False;
ServStoped:=True;
Result:=0;
if WSAStartup($101,Data_)=0 then
begin
Sock:=Socket(AF_INET, SOCK_STREAM,0);
if Sock<>INVALID_SOCKET then
begin
Addr.sin_family:=AF_Inet;
Addr.sin_port:=HToNS(801);
Addr.sin_addr.S_addr:=Inet_Addr("192.168.1.6");
FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
if Connect(Sock,Addr,SizeOf(TSockAddr))<>SOCKET_ERROR then
begin
Form1.Memo1.Lines.Add("Нить запущена!");
repeat
FD_Zero(FDSet);
FD_Set(Sock,FDSet);
Tm.tv_sec:=0;
Tm.tv_usec:=10000;
if Select(0,@FDSet,nil,nil,@Tm)<>0 then
begin
if FD_IsSet(Sock,FDSet) then
begin
if Recv_(Sock,Data) then
Form1.Memo1.Lines.Add(Data)
// выводим все полученное в Memo
else
ServStoped:=False; // сервер упал.выходим
end;
end;
if WrCons then
begin // посылаем в консоль
Send_(Sock,Form1.Edit1.Text+#13#10);
WrCons:=False;
end;
until (not StopThread) or (not ServStoped);
if not StopThread then
Form1.Memo1.Lines.Add("Прервано пользователем") else
Form1.Memo1.Lines.Add("Обрыв на сервере");
CloseSocket(Sock);
WSACleanup;
end else
begin //
Result:=WSAGetLastError;
CloseSocket(Sock);
WSACleanup;
end;
end else
begin //Socket
Result:=WSAGetLastError;
WSACleanup;
end;
end else Result:=WSAGetLastError; //WSAStartup
end;
procedure TForm1.StopClick(Sender: TObject);
begin
StopThread:=False; // "убиваем" нить
// для "убийства" можно использовать и CloseSocket
// пока не определился какой вариант лучше
end;
procedure MsgWaitForSingleObject(Handle: THandle);
begin
repeat
if MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) = WAIT_OBJECT_0 + 1 then
Application.ProcessMessages else
Break;
until True = False;
end;
procedure TForm1.StartClick(Sender: TObject);
var hThread:HWND;
ThreadID,ECode:DWord;
begin
if not(B) then
begin
B:=True;
hThread:=BeginThread(nil,0,@potok,nil,0,ThreadID);
MsgWaitForSingleObject(hThread);
GetExitCodeThread(hThread,ECode);
CloseHandle(hThread);
if ECode<>0 then
MessageDlg("Ошибка :"+SysErrorMessage(ECode),MtError,[MbOk],0);
B:=False;
end else
MessageDlg("Нить УЖЕ работает!!! Хватит",MtError,[MbOk],0);
end;
procedure TForm1.Exec_ConsoleClick(Sender: TObject);
begin
if Length(Edit1.Text)=0 then Exit;
WrCons:=True;
end;
end.
Данный код у меня работает с разных Ос(98,ХР).Повторюсь сервер запускается на ХР SP1.
При коннекте клиентом на сервере запускается и "висит" cmd.exe до тех пор пока я не разорвусь клиентом.
З.Ы.При запуске сервера на SP2 (и дальнейшем коннекте клиентом) cmd.exe запускается и сразу же закрывается.Я все же думаю,что беда в сервере. Вот,примерное такое происходит на сервере:
procedure TForm1.Button1Click(Sender: TObject);
var
St: TStartupInfo;
Pr: TProcessInformation;
begin
ZeroMemory(@St, SizeOf(TStartupInfo));
St.cb := SizeOf(TStartupInfo);
St.wShowWindow := SW_SHOW;
St.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
St.hStdInput := 0; // это я специально,дабы показать
St.hStdOutput := 0;
St.hStdError := 0;
if not (CreateProcess(nil, "cmd.exe", nil, nil, True, 0, nil, nil, St, Pr)) then
MessageDlg("Ошибка:"+SysErrorMessage(GetLastError),MtError,[MbOk],0); // ошибки не будет
CloseHandle(Pr.hProcess);
CloseHandle(Pr.hThread);
end;
← →
Digitman © (2006-01-18 16:14) [7]Отложи на время свои "беды с неожиданным закрытием CMD", у тебя серьезные проблемы еще ДО этого.
Обращаться к визуальным VCL-контролам в контексте доп.потока НЕдопустимо.
← →
GanibalLector © (2006-01-18 21:45) [8]2 Digitman © (18.01.06 16:14) [7]
>Обращаться к визуальным VCL-контролам в контексте доп.потока НЕдопустимо.
Я знаю. Сказал же в [6],что черновой вариант. На самом деле должно быть так :
var CS:TRTLCriticalSection;
procedure MemoOutput(Value:String);
begin
EnterCriticalSection(CS);
Form1.Memo1.Lines.Add(Value);
LeaveCriticalSection(CS);
end;
// вызов MemoOutput("Нить запущена");
initialization
InitializeCriticalSection(CS);
finalization
DeleteCriticalSection(CS);
Тоже и для переменной WrCons надо сделать.
Но только и это НЕ решает моей проблемы!!!
P.S. Вот даже земляк GuAV говорит,что все работает. А у меня чЁто никак :(
← →
GanibalLector © (2006-01-18 21:45) [9]2 Digitman © (18.01.06 16:14) [7]
>Обращаться к визуальным VCL-контролам в контексте доп.потока НЕдопустимо.
Я знаю. Сказал же в [6],что черновой вариант. На самом деле должно быть так :
var CS:TRTLCriticalSection;
procedure MemoOutput(Value:String);
begin
EnterCriticalSection(CS);
Form1.Memo1.Lines.Add(Value);
LeaveCriticalSection(CS);
end;
// вызов MemoOutput("Нить запущена");
initialization
InitializeCriticalSection(CS);
finalization
DeleteCriticalSection(CS);
Тоже и для переменной WrCons надо сделать.
Но только и это НЕ решает моей проблемы!!!
P.S. Вот даже земляк GuAV говорит,что все работает. А у меня чЁто никак :(
← →
GanibalLector © (2006-01-19 01:10) [10]И вот еще : http://headnet.net.ru/dir6/p1370.htm тоже не работает. Тут видать проблема не в коде,а в чем-то другом. :(
← →
Digitman © (2006-01-19 10:51) [11]
> На самом деле должно быть так
Нет, не так.
А хотя бы вот так :
procedure MemoOutput(Value:String);
begin
SendMessage(хэндл_формы, WM_MYMESSAGE, WParam(PChar(Value)), 0);
end;
procedure TMyForm.MyMessageHandler(var Message: TMessage); //обработчик WM_MYMESSAGE
begin
Memo1.Lines.Add(String(PChar(Message.WParam)));
end;
Если поставить и поймать брейкпойнт на
CloseHandle(Pr.hProcess);
cmd-консоль и в этом случае закрывается ?
← →
GanibalLector © (2006-01-19 19:29) [12]2 Digitman © (19.01.06 10:51) [11]
>А хотя бы вот так
Спасибо.Понял.
>Если поставить и поймать брейкпойнт на CloseHandle(Pr.hProcess);
Да,УЖЕ закрыта.
← →
Digitman © (2006-01-20 08:38) [13]
> Да,УЖЕ закрыта
при этом система что-то пишет в Application Events Log ? И/или другие логи ?
← →
GanibalLector © (2006-01-20 09:59) [14]Нет,ничего не пишет
← →
umbra © (2006-01-20 12:29) [15]похоже на супер-пупер файервол ХР СП2
← →
Digitman © (2006-01-20 13:20) [16]
> похоже на супер-пупер файервол ХР СП2
с чего бы "супер-пупер файерволу" снимать cmd-процесс, если ему еще ни одна команда по каналу ввода не поступила ?
непонятно ..
← →
Digitman © (2006-01-20 13:21) [17]вот если только cmd.exe заражен-загажен (лезет в сеть, едва стартовав) - тогда еще понятно ..
← →
umbra © (2006-01-20 13:47) [18]мое предположение - cmd закрывается потому, что подсоединившийся клиент отрубается файерволом.
← →
umbra © (2006-01-20 13:53) [19]и неплохо бы и серверу и клиенту вести подробный лог при работе.
← →
Digitman © (2006-01-20 13:59) [20]
> umbra © (20.01.06 13:47) [18]
Какой такой "клиент" ?
Клиентский Socket же активируется автором в совершенно другом процессе, и этот самый процесс как раз и должен сниматься файрволом с выполнения, но никак не cmd ...
← →
umbra © (2006-01-20 15:18) [21]2 Digitman © (20.01.06 13:59) [20]
> GanibalLector © (18.01.06 13:33) [6]
> При коннекте клиентом на сервере запускается и "висит" cmd.
> exe до тех пор пока я не разорвусь клиентом.
>
← →
Digitman © (2006-01-20 15:29) [22]
> umbra © (20.01.06 15:18) [21]
> до тех пор пока я не разорвусь клиентом
до "разрыва" и дело не доходит.
Как утверждает автор, процесс-сервер, с которым успешно соединился процесс-клиент, средствами CreateProcess успешно выполнил запуск процесса cmd.exe и остановил свое выполнение на брейкпойнте на операторе, следующем СРАЗУ за CreateProcess. При этом, как опять же утверждает автор, процесс cmd.exe едва стартовав тут же снимается с выполнения... В этот момент при такой ситуации состояние клиента серверу абсолютно безразлично - процесс сервера отладчик приостановил на брейкпойнте.
← →
umbra © (2006-01-20 16:16) [23]
>
> if not (CreateProcess(nil, "cmd.exe", nil, nil,
> True, 0, nil, nil, St, Pr)) then
> MessageDlg("Ошибка:"+SysErrorMessage(GetLastError),MtError,
> [MbOk],0); // ошибки не будет
> CloseHandle(Pr.hProcess);
> CloseHandle(Pr.hThread);
может,я чего-то недопонимаю, но по-моему в этом фрагменте написано, что если процесс успешно создан, то его надо сразу же закрыть. или я не прав?
← →
Digitman © (2006-01-20 16:27) [24]
> или я не прав?
Не прав.
Закрытие хендла в дан.случае не означает уничтожение созданного объекта-процесса, теряется лишь доступ тек.процесса к этому объекту.
А даже если ты и был бы прав, то - вникни еще раз в [12] - автор утверждает, что строчка CloseHandle(Pr.hProcess) еще не выполнена (отладчик поймал брейкпойнт на ней и приостановил текущий процесс), а процессу cmd.exe уже приключился кирдык
← →
GanibalLector © (2006-01-20 19:54) [25]Да,фаеврол стоит.При тестах я его закрывал или делал Allow All.
Вирусов вроде нет ;) Неделю назад проверял Касперским.
Даже поставил все update-ты последние в надежде на счастье. Но увы :(
В общем,я свою проблему разрешил.Сделал так : при получении сервером от клиента определенной команды запускаю "cmd.exe /c тут_комманда" и перенаправляю ввод-вывод на файл или pipe.Жду завершения процесса,накапливаю все в буфере,а потом отвечаю клиенту этим буфером.Работает за исключением пары комманд(find и еще что-то). От Лукавого конечно,но работает ;)
А на работе,все работает и так(т.е. через перенаправление cmd на сокет).
Вот такие чудеса !
З.Ы. Спасибо! Персонально Digitman © (19.01.06 10:51) [11]. Принял на вооружение ;)
← →
Лорд Байрон © (2006-01-22 12:00) [26]В какой из инет магазинов лучше регистрироваться чтобы больше покупали и какие проги надо продавать.
Помогите плизззззззззз...
P.S.
Прога создающая стерео изображение годится?
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.009 c