Jump to content
cbPlus

C++ Builder 11.3 / RenameFile() not working?

Recommended Posts

I have written some code from a tutorial. Now I am stuck with
the RenameFile() function from System.SysUtils.hpp

The returnValue_ is always false or 0.

I tried it as Administrator. I checked the file permissions security.
Nothing worked.

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "uTSearchRec.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2* Form2;
TSearchRec SearchRec;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) {}
//---------------------------------------------------------------------------
void __fastcall TForm2::btnSearchClick(TObject* Sender)
{
    String FindFirstPath_ = "C:\\Users\\NO_NO\\OneDrive\\TEMP\\*.*";
    String Caption1_ = "Current Path:\n" + FindFirstPath_;
    String Caption2_ =
        SearchRec.Name + " is " + IntToStr(SearchRec.Size) + "bytes in size";

    FindFirst(FindFirstPath_, faAnyFile, SearchRec);
    lbOutput->Caption = Caption1_ + "\n" + Caption2_;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::btnAgainClick(TObject* Sender)
{
    if (FindNext(SearchRec) == 0) {
		lbOutput->Caption = SearchRec.Name + " is " + IntToStr(SearchRec.Size) +
                           " bytes in size";
    } else
        FindClose(SearchRec);
}

//---------------------------------------------------------------------------

void __fastcall TForm2::btnRenameClick(TObject* Sender)
{
    String const OldFileName_ = SearchRec.Name;
    String const NewFileName_ = OldFileName_ + "bak";
	String const MessageFail_ = "Humpty Bumpty ! Njet Internjet !";
    String const MessageOK_ = "The bether its not get !";
    bool returnValue_ = true;

    try {
		returnValue_ = RenameFile(OldFileName_, NewFileName_);
        lbControlText->Caption = IntToStr(returnValue_);
	}
	catch (...){
		lbOutput->Caption = "NewFileName_ : " + NewFileName_ + "\nOldFileName_ :" +
		OldFileName_ + "\nreturnValue : " + IntToStr(returnValue_);
	}

    lbOutput->Caption = MessageOK_;


    /*
	if ( (RenameFile(OldFileName_, NewFileName_) == false )) {
		lOutput->Caption = MessageFail_;
	} else
		lOutput->Caption = MessageOK_;
	*/
}
//---------------------------------------------------------------------------

 

Header

//---------------------------------------------------------------------------

#ifndef uTSearchRecH
#define uTSearchRecH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <System.SysUtils.hpp>

//---------------------------------------------------------------------------
class TForm2 : public TForm
{
  __published: // IDE-managed Components
	TLabel *lbOutput;
    TButton* btnSearch;
    TButton* btnAgain;
    TButton* btnRename;
	TLabel *lbControlText;
    void __fastcall btnSearchClick(TObject* Sender);
    void __fastcall btnAgainClick(TObject* Sender);
    void __fastcall btnRenameClick(TObject* Sender);
  private: // User declarations
  public: // User declarations
    __fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2* Form2;
//---------------------------------------------------------------------------
#endif

 

Share this post


Link to post
1 hour ago, cbPlus said:

I have written some code from a tutorial. Now I am stuck with
the RenameFile() function from System.SysUtils.hpp

The returnValue_ is always false or 0.

I tried it as Administrator. I checked the file permissions security.
Nothing worked.

RenameFile() does not raise an exception on failure, so your try..catch is useless.  Are you sure FindFirst/FindNext() is even successful to begin with?  You are not doing any error checking on FindFirst().  Did you debug to make sure OldFileName and NewFileName are what you are expecting?  Also, you are using a file path into OneDrive, does OneDrive allow renaming files in this manner to begin with?  Do you have the same problem with local files?

31 minutes ago, Brian Evans said:

Normal practice to use GetLastError to see what the problem is when some Windows APIs fail. 

 

GetLastError function (errhandlingapi.h) - Win32 apps | Microsoft Learn

Note that FindFirst() and FindNext() return the actual error code.

Share this post


Link to post
Posted (edited)

I read the question too fast, the code that should have GetLastError added to see any errors specific to the rename (like file open) is commented out.  

 

Delphi equivalent pattern is:

  if RenameFile(oldName, newName)
  then ShowMessage('File renamed OK')
  else ShowMessage('File rename failed with error : '+ IntToStr(GetLastError));

 

Edited by Brian Evans

Share this post


Link to post
15 minutes ago, Brian Evans said:

Delphi equivalent pattern is:


  if RenameFile(oldName, newName)
  then ShowMessage('File renamed OK')
  else ShowMessage('File rename failed with error : '+ IntToStr(GetLastError));

 

In C++:

if (RenameFile(OldFileName_, NewFileName_))
	lbControlText->Caption = _D("OK");
else
	lbOutput->Caption = _D("NewFileName_ : ") + NewFileName_ + _D("\nOldFileName_ : ") + OldFileName_ + _D("\nError : ") + IntToStr(GetLastError());

Alternatively use RaiseLastOSError() to throw an exception holding the error code:

try {
	if (!RenameFile(OldFileName_, NewFileName_))
		RaiseLastOSError();
	lbControlText->Caption = _D("OK");
}
catch (const EOSError& ex) {
	lbOutput->Caption = _D("NewFileName_ : ") + NewFileName_ + _D("\nOldFileName_ : ") + OldFileName_ + _D("\nError : ") + IntToStr(ex.ErrorCode);
}

 

Share this post


Link to post

SearchRec.Name would only be the filename part and does not include the path. Unless something has changed.  If so, make sure that you add path before the file name.

  • Like 1

Share this post


Link to post
Posted (edited)

Thanks for all the answers. Very, very helpful.
I like this forum.

So. I took your advice and tampered my code. It works now.

 

@silvercoder79
This was the final solution. I didn't recognize that the absolute path
is needed. Thanks.

 

I know the code's syntax is 'simple' coded. But I need this for now
to better understand what's going on. It is actually only
a learning code.

 

Any further ideas are welcome.

 

Anyway. Thank you.

 

 

#include <vcl.h>
#pragma hdrstop

#include "uTSearchRec.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2* Form2;
TSearchRec SearchRec;
String WorkingPath_ = "C:\\Users\\NONO\\OneDrive\\TEMP\\";
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) {}
//---------------------------------------------------------------------------
void __fastcall TForm2::btnSearchClick(TObject* Sender)
{
	String FindFirstPath_ = WorkingPath_ + "*.*";
    String Caption1_ = "Current Path:\n" + FindFirstPath_;
    String Caption2_ =
        SearchRec.Name + " is " + IntToStr(SearchRec.Size) + "bytes in size";

    FindFirst(FindFirstPath_, faAnyFile, SearchRec);
    lbOutput->Caption = Caption1_ + "\n" + Caption2_;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::btnAgainClick(TObject* Sender)
{
    if (FindNext(SearchRec) == 0) {
		lbOutput->Caption = SearchRec.Name + " is " + IntToStr(SearchRec.Size) +
                           " bytes in size";
    } else
        FindClose(SearchRec);
}

//---------------------------------------------------------------------------

void __fastcall TForm2::btnRenameClick(TObject* Sender)
{
    String const OldFileName_ = WorkingPath_ + SearchRec.Name;
    String const NewFileName_ = OldFileName_ + ".bak";
	String const MessageFail_ = "Humpty Bumpty ! Njet Internjet !";
    String const MessageOK_ = "The bether its not get !";
    bool returnValue_ = true;

    try {
		returnValue_ = RenameFile(OldFileName_, NewFileName_);
		if (returnValue_ == false)
            RaiseLastOSError();

		lbControlText->Caption = IntToStr(returnValue_);
	}
	catch (const EOSError& ex){
		lbOutput->Caption = "NewFileName_ : " + NewFileName_ + "\nOldFileName_ :" +
		OldFileName_ + "\nErrorCode : " + String(ex.ErrorCode);
	}

    lbOutput->Caption = MessageOK_;


}
//---------------------------------------------------------------------------

 

Edited by cbPlus
The code view is somewhat wrong with the TABs

Share this post


Link to post

What I don't understand is why you didn't use the debugger or other debugging techniques to check what values were being passed in to the function. That's my idea for you. 

Share this post


Link to post
Posted (edited)

I used and use the debugger. But as I said. I didn't recognize that I have to use the absolute path prior the filenames NewFileName_ and OldFileName_. So I did debug and thought it's ok. I added improtant variables to the watch list.

Simply said, it was a logical thinking error.

 

Recently I bought this book from Mohmad Yakub "C Programming Patterns - The Art of Coding Logic". 🙂

Edited by cbPlus
Book add

Share this post


Link to post
"C:\\Users\\NO_NO\\OneDrive\\TEMP\\*.*"

 

Without the *.* because I thought this is temprorary only for the btnSearch within FindFirst() FindNext()

 

Bad assumption I think.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×