using registry to run a prog at startup - windows

i am trying to run a code in c++ which will result in an .exe file running at startup using registry...but the problem is that the code results fails without showing any errors...i compiled the code in devcpp...
the code is
void createkey(char *path)
{
int reg;
HKEY hkey,Hkey1;
DWORD ptr;
reg=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),0,KEY_SET_VALUE,&hkey);
if(reg=ERROR_SUCCESS)
cout<<"success"<<endl;
else
cout<<"failure"; //(a)
cout<<reg<<endl; //(b)
if(reg==0)
{
RegSetValueEx(hkey,TEXT("key"),0,REG_SZ,(BYTE*)path,strlen(path));
}
}
in the command line failure and 0 got printed as a result of (a) and (b)...(dont know how as the two mean completely opposite things )....the char *path passed to regsetvalueex was "c:/Dev-Cpp/bin/Untitled2.exe"...i am sure that the functions are not working as key doesnt appear in run key(i checked using regedit)...

if(reg=ERROR_SUCCESS)
That's an assignment, you need to use the == operator. Most modern compilers warn about this, be sure to update yours. You probably got an access denied error, can't write to HKLM\Software without elevation.

Standard users don't have write access to HKLM. You need to run this process elevated.

Related

requesting `root` access from user to update `/etc/paths.d`

my app installer uses the standard open DMG, drag to 'Applications' for installation, but I want to update $PATH so my app can be used from the command line.
I think the right way to do this is to call a script on the first time my application runs that creates a file myapp in /etc/paths.d with the text /Applications/myapp/bin followed by a newline(ascii 13):
rm /etc/paths.d/myapp
echo "/Applications/myapp/bin" > /etc/paths.d/myapp
currently I'm getting errors;
rm: /etc/paths.d/myapp: No such file or directory
./myapp.sh: line 2: /etc/paths.d/myapp: Permission denied
I need to trigger a request for the user to type the admin password but I'm not sure how to do that in a way this clearly inform the user what changes I am making to their system and why. (I can add it to the manual but who reads that)
Any suggestions?
PS I need to do the same on linux(hopefully similar) and Windows, but if I can get MacOS sorted hopefully I'll know where to start.
AuthorizationExecuteWithPrivileges is deprecated for a long time, but still present and working in macOS 11 (Big Sur / 10.16). STPrivilegedTask demonstrates how to call the function in a "safe" manner - that is, to properly handle the case where the function might be removed in a future version of the OS.
Usage is something like this (error checking etc is omitted for brevity). This will create a symlink of your executable in /usr/local/bin with the name "my-app":
AuthorizationRef authorizationRef;
OSStatus err;
const char* tool = "/bin/ln";
char *args[] = {
"-sf",
[[[NSBundle mainBundle] executablePath] UTF8String],
"/usr/local/bin/my-app",
nil
};
AuthorizationCreate(nil, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
err = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, nil);
switch (err)
{
case errAuthorizationCanceled:
// user cancelled prompt
break;
case errAuthorizationSuccess:
// success
break;
default:
// an error occurred
break;
}
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
How you use that, is up to you - you could place it behind a menu item ("Install Command Line Tools") like cmake does. If you want to install this at launch time, I'd suggest prompting the user first (and allowing them the option to "don't ask me again").

Is there a pre-existing WinAPI to check if some_app.exe can run w/o providing full-path and running it at any point

Is there a pre-existing WinAPI to check if some_app.exe can run w/o providing full-path and running it at any point?
For example, let's say I want to run cmd.exe or git.exe, but I don't provide with full path . Before I run it, is it possible of me to know prematurely if I can run it without knowing its full path?
One idea that comes to my mind is to emulate the way Windows does it, i.e. to check the current path, then to iterate through %PATH% variable and so on, but is there perhaps a Winapi for this exact purpose?
#RbMm has already pointed out the solution: Use SearchPath API.
The following is an example (a console application) of how to use that API, you can refer to.
#include <windows.h>
#define BUF_SIZE 260
int main()
{
WCHAR appFullPath[BUF_SIZE];
DWORD result = SearchPath(NULL, L"git.exe",NULL, BUF_SIZE, appFullPath, NULL);
if(result == 0)
wprintf(L"SearchPath call get an error: %d \n", GetLastError());
wprintf(L"App full path: %s \n", appFullPath);
getchar();
}
The output of above code:

Removing file in haskell

I am trying to delete a text file in haskell while working in winhugs with help of removeFile function.But it is giving an error that
Program error: price.txt: Directory.removeFile: permission denied
What can be the reason?
According to the Hackage Docs for removeFile, the operation may fail with:
isPermissionError / PermissionDenied The process has insufficient privileges to perform the operation. [EROFS, EACCES, EPERM]
Also, according to the source code there, removeFile is just a thin wrapper around deleteFile in the Win32 API:
removeFile :: FilePath -> IO ()
removeFile path =
#if mingw32_HOST_OS
Win32.deleteFile path
#else
Posix.removeLink path
#endif
Update
After digging around the source code for winhugs, it seems the Windows API function unlink is actually being used to delete a file in Hugs:
primFun(primRemoveFile) { /* remove a file */
int rc;
String s = evalName(IOArg(1));
if (!s) {
IOFail(mkIOError(NULL,
nameIllegal,
"Directory.removeFile",
"illegal file name",
&IOArg(1)));
}
rc = unlink(s);
if (rc != 0)
throwErrno("Directory.removeFile", TRUE, NO_HANDLE, &IOArg(1));
IOReturn(nameUnit);
}
In any case, the previous answer is going to hold up in the sense that any permissions constraint is not introduced by Haskell. Rather, any permissions error would be due to the underlying OS environment (user accounts, open files, permissions, etc).

Uncaught Throw generated by JLink or UseFrontEnd

This example routine generates two Throw::nocatch warning messages in the kernel window. Can they be handled somehow?
The example consists of this code in a file "test.m" created in C:\Temp:
Needs["JLink`"];
$FrontEndLaunchCommand = "Mathematica.exe";
UseFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];
Then these commands pasted and run at the Windows Command Prompt:
PATH = C:\Program Files\Wolfram Research\Mathematica\8.0\;%PATH%
start MathKernel -noprompt -initfile "C:\Temp\test.m"
Addendum
The reason for using UseFrontEnd as opposed to UsingFrontEnd is that an interactive front end may be required to preserve output and messages from notebooks that are usually run interactively. For example, with C:\Temp\test.m modified like so:
Needs["JLink`"];
$FrontEndLaunchCommand="Mathematica.exe";
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
SelectionMove[nb, Next, Cell];
SelectionEvaluate[nb];
];
Pause[10];
CloseFrontEnd[];
and a notebook C:\Temp\run.nb created with a single cell containing:
x1 = 0; While[x1 < 1000000,
If[Mod[x1, 100000] == 0,
Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]];
this code, launched from a Windows Command Prompt, will run interactively and save its output. This is not possible to achieve using UsingFrontEnd or MathKernel -script "C:\Temp\test.m".
During the initialization, the kernel code is in a mode which prevents aborts.
Throw/Catch are implemented with Abort, therefore they do not work during initialization.
A simple example that shows the problem is to put this in your test.m file:
Catch[Throw[test]];
Similarly, functions like TimeConstrained, MemoryConstrained, Break, the Trace family, Abort and those that depend upon it (like certain data paclets) will have problems like this during initialization.
A possible solution to your problem might be to consider the -script option:
math.exe -script test.m
Also, note that in version 8 there is a documented function called UsingFrontEnd, which does what UseFrontEnd did, but is auto-configured, so this:
Needs["JLink`"];
UsingFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];
should be all you need in your test.m file.
See also: Mathematica Scripts
Addendum
One possible solution to use the -script and UsingFrontEnd is to use the 'run.m script
included below. This does require setting up a 'Test' kernel in the kernel configuration options (basically a clone of the 'Local' kernel settings).
The script includes two utility functions, NotebookEvaluatingQ and NotebookPauseForEvaluation, which help the script to wait for the client notebook to finish evaluating before saving it. The upside of this approach is that all the evaluation control code is in the 'run.m' script, so the client notebook does not need to have a NotebookSave[EvaluationNotebook[]] statement at the end.
NotebookPauseForEvaluation[nb_] := Module[{},While[NotebookEvaluatingQ[nb],Pause[.25]]]
NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or##Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]
UsingFrontEnd[
nb = NotebookOpen["c:\\users\\arnoudb\\run.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb];
]
I hope this is useful in some way to you. It could use a few more improvements like resetting the notebook's kernel to its original and closing the notebook after saving it,
but this code should work for this particular purpose.
On a side note, I tried one other approach, using this:
UsingFrontEnd[ NotebookEvaluate[ "c:\\users\\arnoudb\\run.nb", InsertResults->True ] ]
But this is kicking the kernel terminal session into a dialog mode, which seems like a bug
to me (I'll check into this and get this reported if this is a valid issue).

Wrap an executable to diagnose it's invocations

I have a Windows executable (whoami) which is crashing every so often. It's called from another process to get details about the current user and domain. I'd like to know what parameters are passed when it fails.
Does anyone know of an appropriate way to wrap the process and write it's command line arguments to log while still calling the process?
Say the command is used like this:
'whoami.exe /all'
I'd like a script to exist instead of the whoami.exe (with the same filename) which will write this invocation to log and then pass on the call to the actual process.
From a batch file:
echo Parameters: %* >> logfile.txt
whoami.exe %*
With the caveat that you can have problems if the parameters contain spaces (and you passed the in escaping with "), because the command-line parser basically de-escapes them and they should be re-escaped before passed to an other executable.
You didn't note which programming language. It is not doable from a .bat file if that's what you wanted, but you can do it in any programming language. Example in C:
int main(int argc, void **argv)
{
// dump contents of argv to some log file
int i=0;
for (i=0; i<argc; i++)
printf("Argument #%d: %s\n", argv[i]);
// run the 'real' program, giving it the rest of argv vector (1+)
// for example spawn, exec or system() functions can do it
return 0; // or you can do a blocking call, and pick the return value from the program
}
I don't think using a "script" will work, since the intermediate should have a .exe extension for your ploy to work.
I would write a very small command line program to do this; something like the following (written in Delphi/Virtual Pascal so it will result in a Win32 executable, but any compiled language should do):
program PassThrough;
uses
Dos; // Imports the Exec routine
const
PassTo = 'Original.exe'; // The program you really want to call
var
CommandLine: String;
i: Integer;
f: Text;
begin
CommandLine := '';
for i := 1 to ParamCount do
CommandLine := CommandLine + ParamStr(i) + ' ';
Assign(f,'Passthrough.log');
Append(f);
Writeln(f, CommandLine); // Write a line in the log
Close(f);
Exec(PassTo, CommandLine); // Run the intended program
end.
Can't you just change the calling program to log the parameters it used to call the process, and the exit code?
This would be way easier than trying to dig into whoami.exe
Look for whoami.exe, BACK IT UP, replace it with your own executable and see do whatever you like with it's parameters (maybe save them in a text file).
If you can reproduce the crash, use Process Explorer before crashed process is terminated to see its command line.
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

Resources