Page 1 of 1

How FileInstall works (C++)

Posted: 15 Nov 2014, 08:44
by Binary
Hello,
I know, that is not a 'real' AHK question, but I'm searching for an answer for a very long time now.

I'm using C++ and AFAIK, AHK is also written in C++.

What I'm looking for is an installation routine, that makes it possible for me to import data (while compilation; e.g. dll files) and export it while running the program the first time (installing data to a user specific folder on destination computer).

The following one-liner code makes all that possible for me:

Code: Select all

FileInstall, source, dest
I have been looking for a way to imitate this with C++ for very long now, also asking in several C++ forums, but there was no good answer that helped me importing and exporting stuff to my program.

I know, there do exist some programs like InstallShield© or stuff like that, but I'd really like to do that on my own, because I'm talking about just 5 or 6 files that I have to include...

So does anyone in this forum know, how FileInstall command works (I mean, how it is realizied with C++)??

That would help me really much!

Re: How FileInstall works (C++)

Posted: 17 Nov 2014, 02:12
by jNizM
This? From script2.cpp

Code: Select all

ResultType Line::FileInstall(LPTSTR aSource, LPTSTR aDest, LPTSTR aFlag)
{
	bool success;
	bool allow_overwrite = (ATOI(aFlag) == 1);
#ifdef AUTOHOTKEYSC
	if (!allow_overwrite && Util_DoesFileExist(aDest))
		return SetErrorLevelOrThrow();

	// Open the file first since it's the most likely to fail:
	HANDLE hfile = CreateFile(aDest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
	if (hfile == INVALID_HANDLE_VALUE)
		return SetErrorLevelOrThrow();

	// Create a temporary copy of aSource to ensure it is the correct case (upper-case).
	// Ahk2Exe converts it to upper-case before adding the resource. My testing showed that
	// using lower or mixed case in some instances prevented the resource from being found.
	// Since file paths are case-insensitive, it certainly doesn't seem harmful to do this:
	TCHAR source[MAX_PATH];
	size_t source_length = _tcslen(aSource);
	if (source_length >= _countof(source))
		// Probably can't happen; for simplicity, truncate it.
		source_length = _countof(source) - 1;
	tmemcpy(source, aSource, source_length + 1);
	_tcsupr(source);

	// Find and load the resource.
	HRSRC res;
	HGLOBAL res_load;
	LPVOID res_lock;
	if ( (res = FindResource(NULL, source, MAKEINTRESOURCE(RT_RCDATA)))
	  && (res_load = LoadResource(NULL, res))
	  && (res_lock = LockResource(res_load))  )
	{
		DWORD num_bytes_written;
		// Write the resource data to file.
		success = WriteFile(hfile, res_lock, SizeofResource(NULL, res), &num_bytes_written, NULL);
	}
	else
		success = false;
	CloseHandle(hfile);

#else // AUTOHOTKEYSC not defined:

	// v1.0.35.11: Must search in A_ScriptDir by default because that's where ahk2exe will search by default.
	// The old behavior was to search in A_WorkingDir, which seems pointless because ahk2exe would never
	// be able to use that value if the script changes it while running.
	TCHAR aDestPath[MAX_PATH];
	GetFullPathName(aDest, MAX_PATH, aDestPath, NULL);
	SetCurrentDirectory(g_script.mFileDir);
	success = CopyFile(aSource, aDestPath, !allow_overwrite);
	SetCurrentDirectory(g_WorkingDir); // Restore to proper value.

#endif

	return SetErrorLevelOrThrowBool(!success);
}

Re: How FileInstall works (C++)  Topic is solved

Posted: 23 Nov 2014, 10:24
by Binary
Hi again!

Sorry for the late reply. Yes, exactly that was what I was looking for! I rummaged the MSDN a bit and read the part of the Windows Resource System, what exactly is what I was looking for...

Now I have to search for a way to make that platform independent...

Thank's for your help :thumbup: