C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Публикация файла CppWebBrowser
Aptem
Отправлено: 27.09.2003, 13:03


Мастер участка

Группа: Участник
Сообщений: 349



Привет, народ!

Скажите, какими средствами ( программными естественно ) можно текст из Memo сохранить в файле ( например, letter.txt ) на сервере.

Надеюсь все понятно !

Заранее благодарю !
Admin
Отправлено: 27.09.2003, 13:21


Владимир

Группа: Администратор
Сообщений: 1190



Не совсем понял, что значит — на сервере.

Если просто сохранить в файл — то
Memo1->Lines->SaveToFile(FileName);
Aptem
Отправлено: 27.09.2003, 16:25


Мастер участка

Группа: Участник
Сообщений: 349



Да нет...

У меня прога на локальной машине. Необходимо на УДАЛЕННЫЙ сервер послать файл с содержимым Memo.
Гость_pasha
Отправлено: 27.09.2003, 21:21


Не зарегистрирован







А диск на удаленном сервере расшарен или нет ?
Например, у меня на работе на всех компах
расшарен диск сервера с одинаковым именем S.

Ну и сохраните:

Memo1->Lines->SaveToFile("S:\\MyDir\\MemoFile.txt");

или сохраните на локальный диск в файл, а этот файл
и перешлите (скопируйте) на удаленный сервер:

Memo1->Lines->SaveToFile("С:\\MyDir\\MemoFile.txt");
CopyFile(("С:\\MyDir\\MemoFile.txt","S:\\MyDir\\MemoFile.txt",false);

Aptem
Отправлено: 28.09.2003, 11:17


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Гость_pasha @ 27/09/2003, 22:23)
А диск на удаленном сервере расшарен или нет ?
Например, у меня на работе на всех компах
расшарен диск сервера с одинаковым именем S.

А это как... РАСШАРЕН !

Вообщем, я хочу что-то навроде NMHTTP -> Put (...);
Но только вот сервак не разрешает такой метод использовать.
Гость_pasha
Отправлено: 28.09.2003, 18:16


Не зарегистрирован







Расшарен — это ДОСТУП или Sharing.
(Или назначение диску , например на сервере,
сетевого имени, по которому он будет доступен)

В проводнике встаете на диск, идете в "свойства",
"доступ" и ставите "Открыть общий доступ к этой папке".
Диск получает имя по которому может быть доступен
по сети с других компьютеров
(имя можете задать сами любое)

После чего из своих программ можете работать
с этим диском, как будто этот диск у вас на компьютере.
Как я уже сказал, у нас на работе так и сделано,
лежит база и общие файлы на сервере, на диске.
Сетевое имя этому диску на всех компьютерах назначено как S.
И все программы и работают с базой (или общими файлами)
через этот сетевой диск: S:\myDir\MyFile.txt

И для удобства в программах путь к базам не "зашивается"
жестко в программу или Alias, а передается при запуске
программы в параметрах, то есть C:\Proga.exe S:\myDir\MyFile.txt
Aptem
Отправлено: 29.09.2003, 04:01


Мастер участка

Группа: Участник
Сообщений: 349



А если сервак не локальный, а в Нете ! Как я его "расшарю" ?
Admin
Отправлено: 29.09.2003, 13:11


Владимир

Группа: Администратор
Сообщений: 1190



Если через NMHTTP, то вроде в C++Builder 6 есть пример

C:\Program Files\Borland\CBuilder6\Examples\FastNet\HTTP

и help:

CODE
Example

To recreate this example, you will need to create a new blank CBuilder++
application.

Place 4 TMemos, a TEdit, a TOpenDialog, a TNMHTTP, and 7 TButtons on
the form.

Component Descriptions

Memo1: Header Display
Memo2: Body Display
Memo3: Status Display
Memo4: Cookie Display
Edit1: URL input
Button1: HTTP Get
Button2: HTTP Head
Button3: HTTP Options
Button4: HTTP Trace
Button5: HTTP Put
Button6: HTTP Post
Button7: HTTP Delete


Insert the following code into Button1's OnClick event:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 NMHTTP1->Get(Edit1->Text);
}

When Button1 is clicked, the Get method is used to retrieved the document
at the address specified by Edit1. Both the document body and the
document header are retrieved.


Insert the following code into Button2's OnClick event:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
 NMHTTP1->Head(Edit1->Text);

}

When Button2 is clicked, the Head method is used to retrieve the header
of the document at the address specified by Edit1.


Insert the following code into Button3's OnClick event:

void __fastcall TForm1::Button3Click(TObject *Sender)
{
 NMHTTP1->Options(Edit1->Text);
}

When Button3 is clicked, the HTTP options for the document at the address
in Edit1 are retrieved using the Options method. Note: Not all servers
support the Options method.

Insert the following code into Button4's OnClick event:

void __fastcall TForm1::Button4Click(TObject *Sender)
{
 AnsiString S;
 if (InputQuery("Trace Data Required", "Input data to send as trace", S))
   NMHTTP1->Trace(Edit1->Text, S);
}

When Button4 is clicked, the InputQuery function is used to get data from
the user to use as trace data. If the user inputs data and clicks Ok, the
Trace method sends the data to the server as trace data.

Insert the following code into Button5's OnClick event:

void __fastcall TForm1::Button5Click(TObject *Sender)
{
 if (OpenDialog1->Execute())
   {
     NMHTTP1->OutputFileMode = TRUE;
     NMHTTP1->Put(Edit1->Text, OpenDialog1->FileName);
     NMHTTP1->OutputFileMode = FALSE;
   }
}

When Button5 is clicked, OpenDialog1 prompts for a file. If a file is selected,
the OutputFileMode property is set to TRUE, so that the data to be put will
be read from the file specified. The Put method is used to store the file at
the address specified by Edit1. When the file is put, the OutputFileMode
property is returned to FALSE.

Insert the following code into Button6's OnClick event:

void __fastcall TForm1::Button6Click(TObject *Sender)
{
 AnsiString S;
 if (InputQuery("Post Data Required", "Input data to Post", S))
   NMHTTP1->Post(Edit1->Text, S);
}

When Button6 is clicked, the InputQuery function is used to retrieve the
data to be posted. If the Ok button is clicked, the data that was input is
posted using the Post method to the document specified by the address in
Edit1.

Insert the following code into Button7's OnClick event:

void __fastcall TForm1::Button7Click(TObject *Sender)
{
 NMHTTP1->Delete(Edit1->Text);
}

When Button7 is clicked, the Delete method attempts an HTTP Delete of
the document specified by the address in Edit1.


Insert the following code into NMHTTP1's OnAuthenticationNeeded event:

void __fastcall TForm1::NMHTTP1AuthenticationNeeded(TObject *Sender)
{
 AnsiString AnID, APass;

 InputQuery("Authentication required", "Enter a user ID", AnID);
 InputQuery("Authentication required", "Enter a password", APass);
 NMHTTP1->HeaderInfo->UserId = AnID;
 NMHTTP1->HeaderInfo->Password = APass;
 ShowMessage("Authentication information in place, please retry the
previous command");
}

If basic authentication is used to access the document specified by the
address in Edit1, the OnAuthenticationNeeded event is called. In this
example, the InputQuery function is used to retrieve a user ID and
password. These values are then stored in the UserId and Password
properties of the HeaderInfo property (See the THeaderInfo reference). A
message is shown to the user asking them to attempt the HTTP
transaction again once the password and user id are in place.

Insert the following code into NMHTTP1's OnFailure event:

void __fastcall TForm1::NMHTTP1Failure(CmdType Cmd)
{
 Memo1->Text = NMHTTP1->Header;
 Memo2->Text = NMHTTP1->Body;
 switch(Cmd)
   {
     case CmdGET: Memo3->Lines->Add("HTTP GET Failed");
     case CmdPOST: Memo3->Lines->Add("HTTP Post Failed");
     case CmdHEAD: Memo3->Lines->Add("HTTP HEAD Failed");
     case CmdOPTIONS: Memo3->Lines->Add("HTTP OPTIONS Failed");

     case CmdTRACE: Memo3->Lines->Add("HTTP TRACE Failed");
     case CmdPUT: Memo3->Lines->Add("HTTP PUT Failed");
     case CmdDELETE: Memo3->Lines->Add("HTTP Delete Failed");
   }
}

When an HTTP command fails, the OnFailure event is called. In this case,
the header for the returned error is displayed in Memo1, and the body is
displayed in Memo2. Memo3 is updated by checking which command failed
using the Cmd parameter, and adding a specific fail message for each of
the supported commands.

Insert the following code into NMHTTP1's OnRedirect event:

void __fastcall TForm1::NMHTTP1Redirect(bool &Handled)
{
 if (MessageDlg("This site is redirecting you to another site. Allow
redirect?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) ==
mrNo)
   Handled = TRUE;
}

If the document specified by the address in Edit1 redirects the client to
another site for it's content, the OnRedirect event is called. Using the
MessageDlg function, the user is asked to allow the redirect. If the user
selects No, the Handled parameter is set to TRUE, which prevents the
redirect (default action) from taking place. If the user selects Yes, the
default action is taken by the component, and the redirected document is
loaded.

Insert the following code into NMHTTP1's OnSuccess event:

void __fastcall TForm1::NMHTTP1Success(CmdType Cmd)
{
 if (NMHTTP1->CookieIn != "")
   Memo4->Text = NMHTTP1->CookieIn;
 Memo1->Text = NMHTTP1->Header;
 Memo2->Text = NMHTTP1->Body;
 switch(Cmd)
   {
     case CmdGET: Memo3->Lines->Add("HTTP GET Successful");
     case CmdPOST: Memo3->Lines->Add("HTTP POST Successful");
     case CmdHEAD: Memo3->Lines->Add("HTTP HEAD Successful");

     case CmdOPTIONS: Memo3->Lines->Add("HTTP OPTIONS Successful");
     case CmdTRACE: Memo3->Lines->Add("HTTP TRACE Successful");
     case CmdPUT: Memo3->Lines->Add("HTTP PUT Successful");
     case CmdDELETE: Memo3->Lines->Add("HTTP DELETE Successful");
   }
}

When an HTTP command succeeds, the OnSuccess event is called,
signifying the success. In this example, if a cookie is returned from the
remote host in the CookieIn property, it is displayed in Memo4. The header
and body returned from the server in the Header and Body properties,
respectively. The header is displayed in Memo1, and the body is displayed
in Memo2. Memo3 acts as a status screen, displaying that the command
specified by the Cmd parameter was successful.



Aptem
Отправлено: 30.09.2003, 14:29


Мастер участка

Группа: Участник
Сообщений: 349



Мой хостер запрещает использовать NMHTTP -> Put () !!!

Есть ли другие варианты закинуть файл на сервер ?

Спасибо за внимание !!!

Отредактировано Aptem — 30/09/2003, 15:32
Admin
Отправлено: 30.09.2003, 15:19


Владимир

Группа: Администратор
Сообщений: 1190



Возможно, нет, если у хостера это все закрыто и запрещено.

Но разрешает ли хостер запуск на сервере, ну скажем .php скриптов ?
(в котором и будет прописана загрузка некоего файла на сервер,
если это у хостера разрешено)

Пишите .php скрипт, кладете его на сервер,
а из своей программы его вызываете и указываете ему
нужный файл, скрипт загружает этот файл на сервер,
в указанную папку.

Например, здесь, на Valuehost, я тоже не могу напрямую послать
файл на сервер, но у меня есть php-скрипт, который это делает
(и который размещен на сервере) и работает через html-форму:
http://rxlib.ru/Upl/Upload.html
(которая тоже размещена на удаленном сервере)

А если это специально у хостера выставлена против этого защита,
(а сервер наверняка Unix или FreeBSD) то вряд-ли чего выйдет.

Aptem
Отправлено: 01.10.2003, 19:23


Мастер участка

Группа: Участник
Сообщений: 349



Да я бы хотел это все автоматизировать !

Предистория вот какая:
У меня есть приложение на BCB, с помощью которого я хотел раз в день посылать письма. Хостер запрещает использовать NMSMTP->SendMail (). Поэтому я написал php-скрипт, который и отсылает эту почту. Но появилась новая проблема: как передать текст письма на сервер. И вот я решил загружать этот текст в файл, а php-скрипт посылал бы из этого файла письмо.

Вот и вся предистория! Так как же передать файл на сервер ( автоматически, а не с помощью HTML-формы ) !!!

Неужели у проблемы нет решения ???!!!
Гость_Vaska
Отправлено: 01.10.2003, 20:46


Не зарегистрирован







А ты сокеты попробуй (TServerSocket и TClientSocket).
Admin
Отправлено: 02.10.2003, 12:50


Владимир

Группа: Администратор
Сообщений: 1190



QUOTE
Мой хостер запрещает использовать NMHTTP -> Put () !!!


Так. А запрещает ли хостер выход по FTP ?
Усли нет, тогда выходите через компонент NMFTP
(пример в C:\Program Files\Borland\CBuilder6\Examples\FastNet\FTP)
Aptem
Отправлено: 02.10.2003, 18:53


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Admin @ 02/10/2003, 13:52)
Так. А запрещает ли хостер выход по FTP ?
Усли нет, тогда выходите через компонент NMFTP

Спасибо за вариант. Обязательно попробую !!!
Admin
Отправлено: 02.10.2003, 19:09


Владимир

Группа: Администратор
Сообщений: 1190



Также посмотрите:

http://borland.xportal.ru/forum/viewtopic....=asc&highlight=


-----

И еще вариант — сделать форму типа http://rxlib.ru/Upl/Upload.html
Вызывать ее по ShellExecute() и заполнять поля программно из
программы на C++Builder и программно нажать Submit
(вот в чем вопрос — как это сделать !?) wink.gif

Отредактировано Admin — 02/10/2003, 20:13
Aptem
Отправлено: 05.10.2003, 04:12


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Admin @ 02/10/2003, 20:11)
вот в чем вопрос — как это сделать !?

Да уж...
Admin
Отправлено: 06.10.2003, 17:17


Владимир

Группа: Администратор
Сообщений: 1190



Ура !!!!!!!!!!! Получилось !!!!!!!!!!!! biggrin.gif biggrin.gif biggrin.gif

Пришлось переворошить кучу форумов, в том числе и китайских
или японских, на наших тоже только спрашивают, а ответов нет,
но наконец все получилось !

Делаем так:
Создаем форму для загрузки файлов на сервер:
HTML
<html>
Программирование в C++Builder.

Загрузка файлов на сервер.

<FORM ENCTYPE="multipart/form-data"
ACTION="http://site.ru/Upload.php" METHOD=POST name="UploadForm">
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="1500000">
Пароль <input type="text" name="passwd">
Имя файла: <INPUT NAME="userfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Отправить">

(нажмите кнопку ОБЗОР, выберите файл и затем ОТПРАВИТЬ)
</FORM>
</html>


В принимающей форме (Upload.php) перемещаем загруженный файл
из временной папки в постоянную:

CODE
<?php

     if($passwd != 'if5edU7dk4') { print "Пароль неверный.";  return 0;  }
echo "
     Вы загрузили файл размером: $userfile_size байт

     На вашем компьютере файл назывался: $userfile_name
";

     // перемещаем загруженный файл на сервере в папку Upload
     move_uploaded_file($_FILES['userfile']['tmp_name'],
   "/pub/home/site/Upload/".$userfile_name);
?>


Теперь пишем проект на C++Builder, из которого мы будем
автоматически заполнять поля формы — пароль, имя загружаемого
файла, и программно нажмем кнопку Submit на форме.

Делать это мы будем с помощью компонента CppWebBrowser

Заполнение полей формы и нажатие submit особых сложностей
не вызывает:

CODE

// Upload file to server
void __fastcall TFMain::bUploadClick(TObject *Sender)
{
AnsiString slHtmlFormName = "UploadForm"; // <form name="UploadForm"...

IHTMLDocument2 *pHTMLDocument = NULL;
if(SUCCEEDED(CppWebBrowser->Document->QueryInterface(
IID_IHTMLDocument2, (LPVOID*)&pHTMLDocument)))
{
if(pHTMLDocument != NULL)
{
IHTMLElementCollection *pAll = NULL;
if(SUCCEEDED(pHTMLDocument->get_all(&pAll)) && pAll)
{
TVariant vName="userfile", vName2 = "passwd", vName0 = "MAX_FILE_SIZE";
TVariant vIndex=0;

// put into hidden field <hidden...
IDispatch *pDisp0=NULL;
if(SUCCEEDED(pAll->item(vName0, vIndex, &pDisp0)) && pDisp0)
{

IHTMLInputHiddenElement *pSize = NULL;
if(SUCCEEDED(pDisp0->QueryInterface(IID_IHTMLInputHiddenElement,
(LPVOID*)&pSize)) && pSize)
{
pSize->put_value(WideString("150000"));
pSize->Release();
}
pDisp0->Release();
}

// paste into file field <file...
IDispatch *pDisp=NULL;
if(SUCCEEDED(pAll->item(vName, vIndex, &pDisp)) && pDisp)
{
IHTMLInputFileElement* pFile = NULL;
if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLInputFileElement,
(LPVOID*)&pFile)) && pFile)
{
// Copy Full FileName To Clipboard
Clipboard()->SetTextBuf(sFile.c_str());
pFile->select();
// Paste from ClipBoard to "userfile"
CppWebBrowser->ControlInterface->ExecWB(Shdocvw_tlb::OLECMDID_PASTE,
Shdocvw_tlb::OLECMDEXECOPT_DODEFAULT, Variant("userfile"));
pFile->Release();
}
pDisp->Release();
}

// put into input element <input...
IDispatch *pDisp2=NULL;
if(SUCCEEDED(pAll->item(vName2, vIndex, &pDisp2)) && pDisp2)
{

IHTMLInputElement *pInput = NULL;
if(SUCCEEDED(pDisp2->QueryInterface(IID_IHTMLInputElement,
(LPVOID*)&pInput)) && pInput)
{
pInput->put_value(WideString("if5edU7dk4"));
pInput->Release();
}
pDisp2->Release();
}
}
pAll->Release();

}
// click SUBMIT()
IHTMLElementCollection *HTMLForms = NULL;
if(SUCCEEDED(pHTMLDocument->get_forms(&HTMLForms)) && HTMLForms)
{
// slHtmlFormName <form name="UploadForm"...>
TVariant vName3 = slHtmlFormName;
TVariant vIndex3 = 0;
IDispatch *pDisp3 = NULL;
if(SUCCEEDED(HTMLForms->item(vName3, vIndex3, &pDisp3)) && pDisp3)
{
IHTMLFormElement *HTMLForm = NULL;
if(SUCCEEDED(pDisp3->QueryInterface(IID_IHTMLFormElement,
(LPVOID*)&HTMLForm)) && HTMLForm)
{
HTMLForm->submit(); // нажимаем кнопку submit
HTMLForm->Release();
}
pDisp3->Release();
}
HTMLForms->Release();
}

pHTMLDocument->Release();
}
}



Куда интересней здесь обходится система безопасности IE,
для которой мы не можем напрямую в свойстве указать имя
загружаемого файла, мы это делаем через копирование и вставку
этого имени через буфер обмена
CODE


// Copy Full FileName To Clipboard
Clipboard()->SetTextBuf(sFile.c_str());
pFile->select();
// Paste from ClipBoard to "userfile"
CppWebBrowser->ControlInterface->ExecWB(Shdocvw_tlb::OLECMDID_PASTE,
Shdocvw_tlb::OLECMDEXECOPT_DODEFAULT, Variant("userfile"));


В общем, все работает, и теперь вы можете легко
программно из C++Builder заполнять html-формы
и отсылать их на сервер.
(конечно если нет каких-то других ограничений -
запрет на Upload файлов, сессии и др.)

Прикладываю рабочий пример проекта для C++Builder 6 (8 Кб).

Отредактировано Admin — 06/10/2003, 18:20

User Attached Image Скачать файл
Wbr.rar


Aptem
Отправлено: 07.10.2003, 18:07


Мастер участка

Группа: Участник
Сообщений: 349



Огромное спасибо, Admin, прямо сейчас же, еще не снимая ботнок, поробую...

Вернуться в Вопросы программирования в C++Builder