I was making universal steam launcher, that allows to hook steam and any child game with CCLUTCH and automatically restart Steam after quitting the game if steam was started prior launch, or to shut steam down after game if steam was not launched, to prevent accidental hooking of VAC and PB protected games and avoid annoyance of manual restart.
I actually succeeded in automating this process, but partially, cclutch injector was a bottleneck that made me stuck.
Because steam dont allow to know the name and patch of game exe file based on appid (at least not any im aware off, would be helpfull if anyone could tell me which of steam config files i need to read to get some sort of table where id assigned to path and exe), i was aiming for universal solution, by launching game via steam.exe and steam browser protocol command with id as argument and cclutch patching any child proccesses, and thats where the problem appears.
While i can start some games directly by pointing injector to exact exe file, i cannot start steam with injector at all, some game with fresh steam stub will autostart steam and their process will be restarted, but other games have older stub, that does not start steam automatically, also my launched needs to configured individually for every game and pointing it exact exe path, which ruins my intentions to make it 100% universal and automated.
By design it should read any steam URL shortcuts on desktop, get id, name and icon from URL, make a copy of launched into steam\steam folder, delete SBP URL shortcut and create LNK shortcut with same name and icon that points to copy of my launcher with arguments that will pass game id to it, so it could launch any steam game with color clutch automatically - to put it simple, it just converts steam shorctuts and put itsel in a middle between to save time and avoid making bat files and shorctus manually, just wtih one click, it also registers same shortcuts in Game Explorer to make things even easier.
And well after i discovered that inject.exe cant launch Steam, and makes it show only "steam update failed", i started investigation to understand why this thing happens, and thats where i found disasterous behavior of injector in handling pathes.
1) Every command line that should be passed to shell inside "" (this is old workaround for path that includes spaces and other characters that considered as delimiters), but injector doesnt do this, if you will open Sysinternals Process Explorer and look at properties of Steam.exe when its normally launched, they will look like this:
Path:
C:\Program Files\Valve\Steam\Steam.exe
Command line (shellexec call as is):
"C:\Program Files\Valve\Steam\Steam.exe" %args_if_any_should_be_here% // not that "" around path and exe - this is important!!! arguments should be beyond them.
Current dir:
C:\Program Files\Valve\Steam\ // this usually automatically set to same folder from where exe came from, if current dir not stated by shorctut or launcher
And lets look at steam.exe process when we launch it with inject from cclutch:
Path:
C:\Program Files\Valve\Steam\Steam.exe
Command line (shellexec call as is):
C:\Program Files\Valve\Steam\Steam.exe %args_if_any_should_be_here% // no "" around path and exe!!! Problem number 1
Current dir:
C:\ // And thats problem number 2, for some reason injector ignores its own current directory, ignores directory of launched exe and sets current dir to hdd root
Thats causing steam to no load, as it, just as most of properly coded programs, expects to find its files in current work directory and its set to C:\ where obviosly not steam files exist. Steam actually could download missing DLL files and recreate blob files into new working directory, but it also takes extra precautions measures and dont allow to write anything in HDD root, Windows directory and any other vital system directories, to prevent mess, in case if some dummies installed steam to windows or root directory. Thats why steam shows message that its failed to update itself.
Solution is simple - fix injector's behavior, set target exe's directory as current directory by default or at least respect current system directory (from which cclutch was started or which was stated in bat file by cd /d "some directory". Potentially there are some games that uses current directory different than exe directory, from what i remember, Far Cry is one of these games. Sot its better to respect set current directory and pass it to target exe as is.
Extra injector argument that will set current dir prior exe will be really useful.
If game life Far Cry launched by cclutch then game writes and reads several files from c:\ directory, instead of one it should. So not only steam affected, however some games have precaution measures and ignores set CD and detects correct one based on path of their own exe, but not every game is so smart, some even have relative path detection. For example exe sits in bin folder, it loads resources from data folder which is in same folder as bin folder
, and to load data it uses %CD%\..\data\something.pak, it goes 1 folder up from current dir and looks for data folder there. So when you start game.exe with current directory same as exe directory, it works, fine, but if you will start it with color clutch, that sets current directory as c:\ game will look for data directory in non existing path c:\..\data\something.pak , it will try to go into upper directory than c:\. which obviously cannot be done, in will simply cause crash of game.
But that not the only problem, injector really messed up in terms of how to set path and use them in every possible way and does not follow ms recommendations and standard used in most of windows programs.
For example it does not respect relative path in any form, does not respect 8.3 path without "",
Injector works only if it launched this way:
"%full_path_to_injector%\inject.exe" "%full_path_to_cclutch_dll%\cclutch.dll" function "%full_path_target_exe\game.exe" %arguments%
Man, thats ugly and problematic!
It should work this way instead
thats in case if everything is in same folder:
inject.exe cclutch.dll function game.exe %arguments%
this is in case if cclut is in sub folder of game folder and launched from game folder
cclutch\inject.exe cclutch\cclutch.dll function game.exe %arguments%
thats in same case, but launched from cclutch folder
inject.exe cclutch.dll function ..\game.exe %arguments%
thats in case if everything in separate folders, including bat, and all folders are inside one folder
..\inject\inject.exe ..\cclutch\cclutch.dll function ..\bin\game.exe %args%
thats in case if lijector launched from anywhere but CD environmental variable set to game directory where we have exe, in case if full path have spaces, we need to take it into "". otherwise its no necessary
"%fullpath%\inject.exe" %fullpath%\cclutch.dll function game.exe
and i hope its enough to get idea why it doesnt work right now and how it should work.
Thanks.
Full paths are required, and I have no plans on changing this. This is to avoid any problems when people create shortcuts that might change the relative path. Also, there will be a future update to how the current working directory is handled that makes this even more important.
As for quoting paths that contain spaces, that has to be done to correctly parse the command line. You'll note that this is standard practice for every command line application, and is done to avoid any ambiguity, as spaces are used as delimiters between arguments.
I do agree that there needs to be changes on how the CWD is handled. Currently the injector sets the CWD to the directory the game (or application) resides in. While this is useful for some things, such as logging, it makes other things impossible, and certain games will not work unless their CWD is a specific directory *other* than the one that the application resides in. ARMA 2 Beta is one example of this.
I already have a fix for this that will be included in the next release, but there are still a few more bugs and polishing that have to be done before that can come about. Also, August and September are my busiest months with respect to work, so it may be some time before this comes out.