Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > CopyFile не работает в разных версиях Windows


Автор: Гость_Arkady 10.10.2005, 20:12
Приветствую!!!

Прроблема такая - код
#include <vcl.h>
...
CopyFile(src, dest, false);
...

, скомпиленный в Windows XP, не хотит работать в Windows 98 (ничего не делает). Я обращался в разные форумы, были советы даже побитового чтения, но.. полумерой стала сборка проекта в 98. Такой "девяносто восьмой" проект в маздае работает. Но отказывается работать в Xp - просто ничего не делает.
Исследовал, пришел к выводу, что адреса вызова функций из kernel32.dll (или откуда они вызываются) в разных версиях MS разные (ха, открыл Америку [smile] ).

Проблема связана с VCL?

Пробовал прикола ради вместо VCL инклудить хидер windows.h - проблема решается. Но тогда исчезают визуальные компоненты DateTime Pcker и иже с ним. А хочется красоты.

Как быть? Переметнуться во вражеский лагерь Visual Studio с MFC? Не хочется...

С уважением, Аркадий.

Автор: chipset 10.10.2005, 20:41
Модератор: перенесено из C++:Общие вопросы.

Автор: chaos 11.10.2005, 06:25
ты возьми и в зависимости от винды бери адрес CopyFiles из соответствующей длл и копируй себе на здоровье

Автор: The Thing 11.10.2005, 07:24
Не знаю... пробовал через fstream.h открывать файлы... работало и в 98 и Xp.
Тоже самой про fopen(...); через структуру FILE.
Может CopyFile и не работает по каким-то причинам (какие указал ты).. тогда тебе просто надо реализовать свое копирование... а еще лучше предложение chaos

Автор: Гость_Arkady 11.10.2005, 20:43
2chaos:

Вот код, которым я определял адреса вызова CopyFile

HINSTANCE dllInstance; //взято из учебника Архангельского
typedef void (__import * CType(char *,char *, int)); //взято из учебника Архангельского
CType * CopyFil=NULL; //взято из учебника Архангельского
dllInstance=LoadLibrary("kernel32.dll"); //взято из учебника Архангельского
if (dllInstance)
{
CopyFil=(CType *)GetProcAddress(dllInstance, "CopyFileA"); // 77E711B9
if (CopyFil) // <---warn
{
Label1->Caption=Label1->Caption+" 2.kernel32 - ok "+IntToStr(CopyFil);
}

Если таким макаром вызвать копирование один раз, то все норма, но скопировать что-либо второй раз аналогичным образом уже не получается - приложение орет про Access violation. smile.
Что интересно, в строке warn CopyFil после вызова меняет свое значение на что-то левое, например с 77E711B9h на 00000024h. Как ето расценивать?

Хелп, в общем. smile smile smile

2 The Thing: вызов fopen в 98 для копирования вызывает ошибку 3600 файловой системы. smile

Автор: chaos 12.10.2005, 05:50
а ты делаешь FreeLibrary ?

Автор: takedo 12.10.2005, 06:28
Блин, а вы не знали - чтоль? vcl - это Builder!!! А у него такой косяк с третьей версии!!! Только в первой его не было smile

Автор: WickedA 12.10.2005, 18:47
Привет всем! Это я, Гость_Arkady, только зарегистрированный!

2chaos: а как же, делаем-с:

[code =cpp]
...
CopyFil=NULL;
FreeLibrary(dllInstance);
...
[/code]

2takedo: а как бороться? Как тогда использовать API-шную функцию в проекте, в котором задействован VCL??? Ну сильно хоца...

smile smile


Автор: The Thing 13.10.2005, 00:39
Гость_Arkady
Че за хрень... покажи как ты ее вызываешь?..

Автор: WickedA 13.10.2005, 18:38
Hi all!

2 The Thing:

Код

//--- Попытка номер 6
  /*
  TFileStream *sf;
  sf=new TFileStream(strs1,fmOpenRead);
  int size=sf->Size;
  TFileStream *df;
  df=new TFileStream(strd1,fmCreate);
  char *cbuff=new char(size);
  sf->Read(cbuff,size);
  df->Write(cbuff,size);
  delete [] cbuff;
  delete sf;
  delete df;

  TFileStream *sf1;
  sf1=new TFileStream(strd1,fmOpenRead);
  int size1=sf1->Size;
  TFileStream *df1;
  df1=new TFileStream(destin,fmCreate);
  char *cbuff1=new char(size1);
  sf1->Read(cbuff1,size1);
  df1->Write(cbuff1,size1);
  delete [] cbuff1;
  delete sf1;
  delete df1;   */
    //----Конец попытки номер 6

  //--- Попытка номер 3
  //int h1=CopyEx(strs1, strd1,false,false);
  //DeleteFile(strd1);
  //int h2=CopyEx(strd1, strd2,true,false);
  //---- Конец попытки номер 3


  // --- Попытка номер 4
  //spawnl(P_WAIT,"copy","copy",strs1,strd1,"\>rep.txt",NULL);
  //spawnl(P_WAIT,"copy","copy",strd1,strd2,"\>rep.txt",NULL);
  //-- Конец попытки номер 4

  //Попытка номер 5
  /*
  FILE *in, *out1;
  in=fopen(strs1,"rb");
  out1=fopen(strd1,"wb+");
  int c;
  while ((c=getc(in))!=EOF)
  {
  putc(c,out1);
  }
  fclose(in);
  fclose(out1);

  FILE *in2, *out2;
  in2=fopen(strd1,"rb");
  out2=fopen(destin,"wb+");
  int c1;
  while ((c1=getc(in2))!=EOF)
  {
  putc(c1,out2);
  }

  fclose(in2);
  fclose(out2); */
  //--Конец попытки номер 5--------------



А вот как выглядит мой API-шный вызов целиком:

Код

//#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
AnsiString ir="Copy in Win failed";
//AnsiString ir1="Copy";

HINSTANCE dllInstance;
typedef void (__import * CType(char *,char *, int));
CType * CopyFil=NULL;
dllInstance=LoadLibrary("kernel32.dll");
if (dllInstance)
 {
 CopyFil=(CType *)GetProcAddress(dllInstance, "CopyFileA"); // 77E711B9
  if (CopyFil)
  {
  Label1->Caption=Label1->Caption+" kernel32 - ok "+IntToStr(CopyFil);
  }
 }
Label1->Caption=Label1->Caption+" nicht ";
if (CopyFil("file_src.tst","file_dest.tst",false)) MessageBox(NULL,ir.c_str(),ir.c_str(),MB_ICONSTOP);
CopyFil=NULL;
FreeLibrary(dllInstance);
//копируем 2-ой раз, контрольный.
dllInstance=LoadLibrary("kernel32.dll");
if (dllInstance)
 {
CopyFil=(CType *)GetProcAddress(dllInstance, "CopyFileA"); // 77E711B9
  if (CopyFil)
  {
  Label1->Caption=Label1->Caption+" kernel32 - ok "+IntToStr(CopyFil);
  }

 if (CopyFil("file_src2.tst","file_dest2.tst",false)) MessageBox(NULL,ir.c_str(),ir.c_str(),MB_ICONSTOP);
 }
CopyFil=NULL;
FreeLibrary(dllInstance);
}
//---------------------------------------------------------------------------


Вот...

Автор: SergeCpp 14.10.2005, 06:56
typedef void (__import * CType(char *,char *, int));

This function copies an existing file to a new file. A remote application programming interface (RAPI) version of this function exists, named CeCopyFile (RAPI). 

BOOL CopyFile(
  LPCTSTR lpExistingFileName, 
  LPCTSTR lpNewFileName, 
  BOOL bFailIfExists 
); 
Parameters
lpExistingFileName 
[in] Long pointer to a null-terminated string that specifies the name of an existing file. 
lpNewFileName 
[in] Long pointer to a null-terminated string that specifies the name of the new file. 
bFailIfExists 
[in] Boolean that specifies how this operation is to proceed if a file of the same name as that specified by lpNewFileName already exists. If this parameter is TRUE and the new file already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds. 
Return Values
Nonzero indicates success. Zero indicates failure. To get extended error information, call GetLastError.

Remarks

Что интересно, в строке warn CopyFil после вызова меняет свое значение на что-то левое, например с 77E711B9h на 00000024h. Как ето расценивать?

именно из-за потери возврата

у Вас VOID

надо BOOL 

Автор: Neitron 14.10.2005, 09:49
Цитата(takedo @ 12.10.2005, 06:28)
Блин, а вы не знали - чтоль? vcl - это Builder!!! А у него такой косяк с третьей версии!!! Только в первой его не было smile

Не понимаю связь между Апи и VCL

Автор: WickedA 14.10.2005, 18:38
И снова здрасти!

Все это хорошо, но хочется знать, почему мой проект с API-шной функцией CopyFile, содержащий vcl, скомпилированный и собранный в WinXP, не захотел копировать файл в Win98. smile А тот же проект, но собранный в Win98, копирует как миленький (в Вин98).

2 SergeCPP: адрес возврата теряется именно из-за неверного определения типа? Я попробую...
Но что ж мне теперь, обе свои книги Архангельского в трэш посылать?
smile smile smile

Автор: Fixin 14.10.2005, 19:20
Цитата(WickedA @ 14.10.2005, 19:38)
собранный в WinXP, не захотел копировать файл в Win98.
Потому шо у этих виндов ядра немного разные (немног - ууууоооочень мягко сказано)

Добавлено @ 19:22
если скомпилить в 98-м, то и в ХР работать будет. Хотя странно, ведь адреса функций в таком случае одинаковые должны быть? Что-то тут не то!

Автор: SergeCpp 17.10.2005, 06:15
1. Вместо Архангельского следует читать Страуструпа — о языке,
Джеффри Рихтера — о WinAPI,
Свена Шрайбера и Неббета и Соломона с Руссиновичем — о Native API (три книги)

Всего — пять книг

Шестая работа (не книга) — прекрасные комментарии Сергея Деревяго http://ders.angen.net/cpp3/cpp3comm/revisions.html

И вообще, http://ders.angen.net/cpp3/

2. Вообще, причём тут адреса, друзиа!

Почему Вы, СЭР, не линкуете с KERNEL32.LIB ?

И не нужна будет эта не нужная (в данном случае) катавасия

А хеадер — если функция не описана, сделайте описание в своём хеадере

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)