cbitservices
asked on
Previous Question Continued...
I have now identified where the file is and that it is definitely there when the function reaches that point. I have also checked the destination path as well and that seems ok. But it appears that the function still fails at that point. Any ideas what I can do now? Thanks,
Colin.
Colin.
Pardon my ignorance, but I have no idea what you are talking about. Could you post the link to your previous question on this subject and or elaborate on your problem a little more?
Exceter
Exceter
ASKER
Sorry,
The previous question which was effectively resolved was at: https://www.experts-exchange.com/questions/20533520/A-DLL-with-an-exported-function-which-will-copy-a-file.html
I "continued" the question because the new problem was related to but carried on from the existing one. I therefore felt it fairest to post a new question.
The new problem is as follows:
I have now created a DLL with a procedure which copies a file. The procedure works when I run it OK. However, if the file exists at the target location the dll crashes. I need it to exit gracefully so that the program that calls it continues to run. So I need it to: copy the file if it doesn't exist at the target location, but otherwise to ignore it. Is there a dir function or similar with which I could determine whether or not the file currently exists?
The previous question which was effectively resolved was at: https://www.experts-exchange.com/questions/20533520/A-DLL-with-an-exported-function-which-will-copy-a-file.html
I "continued" the question because the new problem was related to but carried on from the existing one. I therefore felt it fairest to post a new question.
The new problem is as follows:
I have now created a DLL with a procedure which copies a file. The procedure works when I run it OK. However, if the file exists at the target location the dll crashes. I need it to exit gracefully so that the program that calls it continues to run. So I need it to: copy the file if it doesn't exist at the target location, but otherwise to ignore it. Is there a dir function or similar with which I could determine whether or not the file currently exists?
ASKER
I have now got this far:
#include <windows.h>
extern "C" short _declspec(dllexport) _stdcall CopyAFile(HWND MainHandle, HWND DialogHandle, const char *pInstallDir, const char *pSupportDir, const char *pUser, const char *pCompany, const char *pSerial, const char *pAdditional)
{
const int DirStrLen = GetSystemDirectory(NULL,0) ; // Find length of the directory string.
char *DirStrPtr = new char[DirStrLen + 1]; // Allocate space for the string luss the NUL at the end.
GetSystemDirectory(DirStrP tr,DirStrL en); // Get the directory string.
string FilNam2 = pSupportDir;
string FilNam3 = FilNam2 + "\\msvbvm60.dll";
string FilNam = DirStrPtr; // Copy to a real string.
delete [] DirStrPtr; // Delete theC-style string.
char envvar[] = FilNam;
FilNam = FilNam + "\\msvbvm60.dll"; // Create filename from the path.
//FilNam = "c:\\windows\\profiles\\co lin blakemore\\desktop\\msvbvm 60.dll";
//MessageBox(NULL,FilNam3. c_str(),"T he FilNam string",MB_OK);
char pathbuffer[_MAX_PATH];
char searchfile[] = "msvbvm60.dll";
_searchenv( searchfile, envvar, pathbuffer );
if( *pathbuffer != '\0' )
return 1;
else
return CopyFile(FilNam3.c_str(),F ilNam.c_st r(),TRUE)! =0;
}
But unfortunately it produces a compile error as follows and I can't see what I need to do to overcome it. I believe it will work if I can sort out this last problem (well I hope so anyway!).
#include <windows.h>
extern "C" short _declspec(dllexport) _stdcall CopyAFile(HWND MainHandle, HWND DialogHandle, const char *pInstallDir, const char *pSupportDir, const char *pUser, const char *pCompany, const char *pSerial, const char *pAdditional)
{
const int DirStrLen = GetSystemDirectory(NULL,0)
char *DirStrPtr = new char[DirStrLen + 1]; // Allocate space for the string luss the NUL at the end.
GetSystemDirectory(DirStrP
string FilNam2 = pSupportDir;
string FilNam3 = FilNam2 + "\\msvbvm60.dll";
string FilNam = DirStrPtr; // Copy to a real string.
delete [] DirStrPtr; // Delete theC-style string.
char envvar[] = FilNam;
FilNam = FilNam + "\\msvbvm60.dll"; // Create filename from the path.
//FilNam = "c:\\windows\\profiles\\co
//MessageBox(NULL,FilNam3.
char pathbuffer[_MAX_PATH];
char searchfile[] = "msvbvm60.dll";
_searchenv( searchfile, envvar, pathbuffer );
if( *pathbuffer != '\0' )
return 1;
else
return CopyFile(FilNam3.c_str(),F
}
But unfortunately it produces a compile error as follows and I can't see what I need to do to overcome it. I believe it will work if I can sort out this last problem (well I hope so anyway!).
ASKER
Sorry, the compile error is: "error C2075: 'envvar' : array initialization needs curly braces"
ASKER
OK, I can see that FileNam is a character array and I can see that FilNam is a string type and that envvar is an array so I suppose I need to convert the string to a character array, but how do I do that?
ASKER
Sorry, what I meant was...
I can see that FilNam is a string type and that envvar is an array so I suppose I need to convert the string to a character array, but how do I do that?
Hope that clarifies what I am thinking.
I can see that FilNam is a string type and that envvar is an array so I suppose I need to convert the string to a character array, but how do I do that?
Hope that clarifies what I am thinking.
It looks like you have a lot of "junk DNA" in that code. Try explaining what you want to do. It looks like perhaps you want to locate the particular file which might be in a directory that is on the PATH and then you want to copy that file into a different directory. Is that the case? If so, why not just say so?
-- Dan
-- Dan
ASKER
I have also now realised that the searchenv function only searches through PATH, LIB environments, etc. So I don't think this is going to work. Is there another function I can use to find out whether a file is present, or a dir function which would do the same job?
ASKER
No, I want to copy a file to the windows system directory if it is not already there; I am not a C++ programmer and therefore don't know the functions available. Help would be appreciated.
ASKER
OK, you can forget it now, I've sorted it! I found the functions _findfirst and _chdir and with these together I have achieved my goal. The question can therefore be cancelled. Thank you.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> I want to copy a file to the windows system directory if it is not already there;
Do you know about the GetWindowsDirectory() and GetSystemDirectory() functions. They return the paths you are looking for.
And if you want to find just one, specific file, don't use FindFirstFile() etc. That has a lot of overhead. the traditional approach is to use GetFileAttributes(). If the file doesn't exist it returns 0xFFFFFFFF. This isn't quite as straightforward, but it is less work---for the programmer and the OS.
Do you know about the GetWindowsDirectory() and GetSystemDirectory() functions. They return the paths you are looking for.
And if you want to find just one, specific file, don't use FindFirstFile() etc. That has a lot of overhead. the traditional approach is to use GetFileAttributes(). If the file doesn't exist it returns 0xFFFFFFFF. This isn't quite as straightforward, but it is less work---for the programmer and the OS.
ASKER
Hi Nietod,
I have accepted your comment as an answer because you have given me valuable further information which I did not know, and should oviously be aware of; thanks for that.
However, I have got it all working now and as long as it works on Windows '95, '98, ME, 2000 and XP. I will be very happy. Of course, I take your point and appreciate the assistance. I will also look at changing these to use the functions you suggest a bit later on, but at the moment, as time is of the essence, and I have wasted far too much just trying to get this working already! I feel I have to come back to it later. Perhaps I can contact you later if I need more assistance with this when I return to it (Of course this could be sooner than I think if I find I have problems with either of the systems I mentioned above; I still have to test on all of them yet; I have only tested on ME so far!). Thanks, again.
I have accepted your comment as an answer because you have given me valuable further information which I did not know, and should oviously be aware of; thanks for that.
However, I have got it all working now and as long as it works on Windows '95, '98, ME, 2000 and XP. I will be very happy. Of course, I take your point and appreciate the assistance. I will also look at changing these to use the functions you suggest a bit later on, but at the moment, as time is of the essence, and I have wasted far too much just trying to get this working already! I feel I have to come back to it later. Perhaps I can contact you later if I need more assistance with this when I return to it (Of course this could be sooner than I think if I find I have problems with either of the systems I mentioned above; I still have to test on all of them yet; I have only tested on ME so far!). Thanks, again.
ASKER
OK, so I got too cocky! :-) It doesn't work on Win 95! I presume that this is due to the reasons you said. So it looks like I have to tackle the other functions as you suggested now. The function I have at present is:
#include <windows.h>
#include <direct.h>
#include <io.h>
#include <time.h>
extern "C" short _declspec(dllexport) _stdcall CopyAFile(HWND MainHandle, HWND DialogHandle, const char *pInstallDir, const char *pSupportDir, const char *pUser, const char *pCompany, const char *pSerial, const char *pAdditional)
{
const int DirStrLen = GetSystemDirectory(NULL,0) ; // Find length of the directory string.
char *DirStrPtr = new char[DirStrLen + 1]; // Allocate space for the string luss the NUL at the end.
long hFile;
struct _finddata_t c_file;
GetSystemDirectory(DirStrP tr,DirStrL en); // Get the directory string.
string FilNam2 = pSupportDir;
string FilNam3 = FilNam2 + "\\msvbvm60.dll";
string FilNam = DirStrPtr; // Copy to a real string.
_chdir( DirStrPtr);
delete [] DirStrPtr; // Delete theC-style string.
FilNam = FilNam + "\\msvbvm60.dll"; // Create filename from the path.
//FilNam = "c:\\windows\\profiles\\co lin blakemore\\desktop\\msvbvm 60.dll";
if( (hFile = _findfirst( "msvbvm60.dll", &c_file )) == -1L )
//{MessageBox(NULL,"File Not Found","The FilNam string",MB_OK);
return CopyFile(FilNam3.c_str(),F ilNam.c_st r(),TRUE)! =0;
//}
else
//{MessageBox(NULL,"File Found","The FilNam string",MB_OK);
return 1;//}
}
and this works on Win ME and XP. However, when I tried it on '95 GP Install returned the error "Error loading extension"
I would be very grateful (and very generous with my points! :-) ) if you could tell me how to use the new functions in the above routine and thereby avoid me having to tackle the "cannot convert... " errors which I KNOW I will otherwise encounter! Thanks,
Kindest regards,
Colin.
#include <windows.h>
#include <direct.h>
#include <io.h>
#include <time.h>
extern "C" short _declspec(dllexport) _stdcall CopyAFile(HWND MainHandle, HWND DialogHandle, const char *pInstallDir, const char *pSupportDir, const char *pUser, const char *pCompany, const char *pSerial, const char *pAdditional)
{
const int DirStrLen = GetSystemDirectory(NULL,0)
char *DirStrPtr = new char[DirStrLen + 1]; // Allocate space for the string luss the NUL at the end.
long hFile;
struct _finddata_t c_file;
GetSystemDirectory(DirStrP
string FilNam2 = pSupportDir;
string FilNam3 = FilNam2 + "\\msvbvm60.dll";
string FilNam = DirStrPtr; // Copy to a real string.
_chdir( DirStrPtr);
delete [] DirStrPtr; // Delete theC-style string.
FilNam = FilNam + "\\msvbvm60.dll"; // Create filename from the path.
//FilNam = "c:\\windows\\profiles\\co
if( (hFile = _findfirst( "msvbvm60.dll", &c_file )) == -1L )
//{MessageBox(NULL,"File Not Found","The FilNam string",MB_OK);
return CopyFile(FilNam3.c_str(),F
//}
else
//{MessageBox(NULL,"File Found","The FilNam string",MB_OK);
return 1;//}
}
and this works on Win ME and XP. However, when I tried it on '95 GP Install returned the error "Error loading extension"
I would be very grateful (and very generous with my points! :-) ) if you could tell me how to use the new functions in the above routine and thereby avoid me having to tackle the "cannot convert... " errors which I KNOW I will otherwise encounter! Thanks,
Kindest regards,
Colin.
ASKER
I have continued this question at: https://www.experts-exchange.com/questions/20535080/The-longest-question-in-the-history-of-EE-I-am-sure.html so that I can award more points for assistance. Thanks,
Colin.
Colin.
>> ) It doesn't work on Win 95! I presume that this is due to the reasons you said.
Probably not.
>> However, when I tried it on '95 GP Install returned the error "Error loading extension"
That sounds like it can't load the DLL? maybe?
You could create a C++ program that tries to load the DLL (just use LoadLibrary() and see if it succeeds. You don't have to be fancy. You can do this in a console program and just print the results to the console.
somethig like
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE LibHnd = LoadLibrary("specify the path here. Two backslashes for each one needed");
if (LibHnd == 0)
cout << "could not load"
return 0;
};
If there is an error, tne try looking at the error code form GetLastError() and look up its description in the error look up under tools menu in VC.
Probably not.
>> However, when I tried it on '95 GP Install returned the error "Error loading extension"
That sounds like it can't load the DLL? maybe?
You could create a C++ program that tries to load the DLL (just use LoadLibrary() and see if it succeeds. You don't have to be fancy. You can do this in a console program and just print the results to the console.
somethig like
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE LibHnd = LoadLibrary("specify the path here. Two backslashes for each one needed");
if (LibHnd == 0)
cout << "could not load"
return 0;
};
If there is an error, tne try looking at the error code form GetLastError() and look up its description in the error look up under tools menu in VC.
ASKER
I'm not sure how to do this. I am developing on an ME computer, and it works OK on there. When I try it on a '95 it fails to load. I don't have the development environment on the '95 machine because it is simply a test machine (which I have just done a reformat and installation of Windows '95 on).
But you can (coudl have) written the above program on the ME computer and then copy it to windows 95.
He Colin,
I see that this question is old but I have the same problem as you now. I use Gp-install and a dll made in MSvisual C++ (winxp) to make a serial key checker. I have the same function declaration, and with dumpbin I can see if it is exported. In GP-install I set the function and via a MessageBox I see that it loads the dll.
Now when you put nothing in you function code(just the messagebox) and return 1 the function also crashes!
In the gp-install help, they say:"when the function returns 1 the installer continues normally".
I don't get it.
Check my question
https://www.experts-exchange.com/questions/21007268/installer-serial-key-in-dll-extention.html
Herman
I see that this question is old but I have the same problem as you now. I use Gp-install and a dll made in MSvisual C++ (winxp) to make a serial key checker. I have the same function declaration, and with dumpbin I can see if it is exported. In GP-install I set the function and via a MessageBox I see that it loads the dll.
Now when you put nothing in you function code(just the messagebox) and return 1 the function also crashes!
In the gp-install help, they say:"when the function returns 1 the installer continues normally".
I don't get it.
Check my question
https://www.experts-exchange.com/questions/21007268/installer-serial-key-in-dll-extention.html
Herman
ASKER
Colin.