Determine when my Application is run for the very first time - c++

I have a Native WinApi C++ Application that finds media(.wmv, .mp3 etc.) files in a specified directory & creates random playlists. The first time the application is run(& only the first time) I want to prompt the user to specify a 'home' directory that the Application will always check for media files & create a playlist from.
My Problem: I dont know of a way how I could determine when the Application is run for the 1st time?
Is there a standard way, maybe a Win32 function that I can use to detect when the Application is run for the 1st time?
Some ideas I have come up with are: (but they seem like hacks or overkill(installer idea))
The application .exe is 322kb(which is tiny & doesn't require an
installer right?) in size so I could create an installer (I was
thinking if someone is installing the application then I know its the
first run & I can prompt them then).
I could have a text file(or xml) called appData.txt & have the 1st
line where I store the home path directory. So "home_path=undefined",
on application run, I look in the text file, if the home_path ==
undefined then I prompt them to specify a home path if its not undefined then I read that directory for media files.
Any ideas of how I can determine when my Application is run for the very first time?

In the installer you could create a registry value for your program.
Then when you start your program, check the registry value.
When you run the program for the first time update that value to so you know it's been run already.

I would use the text file because you are going to have to store the user's directory somewhere anyway, might as well use it for first run detection as well. It has the added bonus that if the file is deleted, you will know that you have to prompt the user again since you no longer know what their home directory is.

You can set some registry value when your App runs for first time and check it on every run. If it is already set then App was already run. If not - set it.

Create a log file on first run. If it exists, then it's not the first time.
try
{
// open log.txt
// do second time run logic here
}
catch(file does not exist)
{
// create log.txt
// first run logic here
}

Related

How do I launch an exe that's in the same subfolder as the main one? (C++)

I'm working on a program download manager with options to open the app you've downloaded.
You can download an app and it would be here:
.../programfiles/pub/appmanager/apps/APPHERE.exe
And the main program would be in
.../programfiles/pub/appmanager/MAINFILE.EXE
I need to find a way to start the app. As seen below, i've tried many ways of doing it (system, ect).
(also system() only opens apps in the same directory so i could do something there).
I can do a separate application, but if someone knows how to implement it into a .NET gui, that would be helpful
I tried:
ShellExecute, System, Create Process
(help me on this one im confused)
EDIT:
I need it so that it makes the full directory.
I try something like :
system(app/pxws.exe)
and it wont work
and i tried to merge strings with getmaindirectory and it says not found
To get a new path that is relative to the EXE of the current process, you can do the following:
Retrieve the calling process's full EXE path via GetModuleFileName() or .NET equivilent.
Strip off the filename portion (MAINFILE.EXE) using System.IO.Path.GetDirectoryName().
Append the desired relative path segment (apps/APPHERE.exe) using System.IO.Path.Combine().
Then you can use the new path with whatever API you need.

Master volume control in Windows, run on startup

Functions like endpointvolume and waveoutSetVolume only works for the application itself, and not the entire computer. Im looking for help, at finding options for code that will:
Control the master volume (The whole pc volume not only one application)
When opened (exe file) the code will place it self in the startup folder on the pc. I have thought of setPathway, but couldn't get it to work.
You can use SetMasterVolume(). As for making it start every time, see here: Add Application to Startup (Registry)

Proper path syntax for calling system() (as admin) to execute a .bat from a specific location?

I have a simple program that reads in a basic config file which contains a user provided path. I'm trying to use that path to call system to execute a .bat that resides at the location provided. I'm able to pass the stored path directly into system and it attempts to run the .bat fine, but it needs to try and run it as an admin. I came across the following post: How to call system() in an opened administrator program and gives it the same privileges?
I'm building the string as indicated in the above post, but when I try and pass this new string into system, it tells me "The system cannot find the file specified". Here's the (most likely wrong) way I'm building the string that I pass into system.
std::string adminFilePath = "runas /user:<admin-user> \"";
adminFilePath.append(configFileSettings.path.c_str()); //Append the path of the file that we got from the config file.
adminFilePath.append("\"");
system(adminFilePath.c_str());
My assumption is that I'm should be trying to build a basic string representing what I'd type right into a cmd window to execute the .bat, but obviously I'm wrong somewhere.
Check file name, that you dont use single . Check current folder for program you'really running if path is relative Do not use system... especially if you have non-an so folder/file names. system () is ancient attempt to implement posix function and supports only ANSI and may be confused by modern quoted arguments as well. Use execve or spawn.
In fact, you can avoid running runas at all Requesting administrator privileges at run time

Why would a program run when launch from windows but not the command prompt?

I wrote a small C++ program in VS2k8. When I launch it from windows (double click the exe file) it runs fine. When I go to the command prompt and try to run it it will hang and eventually crash. I've created test programs with simple outputs that work fine both ways.
Is there something I'm missing? I'm relatively new to programming. I'm trying to launch this program using the VBA shell command but it produces the same outcome as the command prompt.
The funny thing is it was working fine at first until I went in to change the value of a constant variable and rebuilt it (I didn't think that had anything to do with it but I changed it back with no success). No settings where changed.
Edit: I've name it time.exe and than copies.exe (when I tried copying and pasting the code into a new project). The actual code is about 250 lines, not sure what part of it would be causing the issue. It opens a .csv file, loads the information into vectors, and then compares the vectors to each other (adding something to the end of it if it meets certain conditions). It than outputs the file to another .csv file.
Might suggest that the current directory on start up is different and this is causing your issue as you make some assumptions about the current path or drive?

Cannot access INI files in "Program Files"

I wrote this C++ application that needs to check an INI file (“preference.ini”), and eventually modify it (e.g. if the user does not want to see the introduction form anymore). I created it in WinXP, and it works fine on the system where I compiled it (in many locations, including “Program Files”).
Problem:
In Win 7, it works fine if I put the complete program folder under “C”:\” (e.g. “C:\MyProgram”), but if I put it in “C:\Program Files (x86)\MyProgram”, it just retrieves some mysterious data (values not present in my INI file). When I change some settings and save them to file, it (apparently) save the changes (get no errors, but the changes are not there when I go and open the file...
I had some similar issue on a system with another WinXP system (not the one where I compiled it.
I used 'getcwd' to define the path at runtime, and I verified that it is getting it right, even under "Program Files (x86)":
char currentPath[MAXPATH];
getcwd(currentPath, MAXPATH);
std::string licensePath(currentPath);
licensePath.append("\\dat\\preference.ini");'
Any ideas? Thanks in advance for your help.
The answer is as #Kirill has already said - Win7 won't let you write data into Program Files unless you have higher than normal permissions (Run as Administrator). In this case it may be redirecting your file writes so that they still apear to work, but the data itself is not stored in Progam Files.
To add to his answer: In general (unless you want to run your app as an administrator), you should not write any program data to the Program Files folder.
Application settings should be stored in one of the AppData folders. You can get to your user's appdata manually by going to your start menu Search box (Vista/Win7) and typing %appdata%.
To find this location in your code, use SHGetFolderPath with CSIDL_APPDATA (current user) or CSIDL_COMMON_APPDATA (all users).
It could be related to that Windows use virtualization of the file system. You could read here about it. Check if your INI file is located in <root>\Users\<User_name>\AppData\Local\VirtualStore.
Seems to me that the licensePath: getcwd() + "\\dat\\preference.ini" is not what you would expect.
Log this value (console or in a log file) and see what exactly is the value of licencePath is when running you program from different folders.
This article is about game development but has the best description of how and why this happens that I've been able to find
http://msdn.microsoft.com/en-us/library/ee419001(VS.85).aspx
This paragraph from the article describes what is happening most likely -
Attempting to create or write a file
or directory under a folder which does
not grant write permission to the
process will fail under Windows Vista
if the application does not have
administrative privileges. If your
32-bit game executable is running in
legacy mode, because it did not
declare a requested execution level,
its write operations will succeed, but
they will be subjected to
virtualization as described in the
section "UAC Compatibility with Older
Games" later in this article.