I'm using System function System(mypath/test.xls) to open and edit an excel sheet in C++ run time. It opens my excel sheet, allows me to edit ans close the same. After closing the excel sheet, the control goes to the code again. Everything works fine unless there is already some other excel sheet opened. If there is some other excel sheet already opened in the machine, I will not able to edit and close so that control goes to code. Can anyone suggest any solutions for this issue.
What is happening is your System(..) function call is asking the Windows shell to find the application associated with your file (test.xls) , which is Excel. Then if Excel is already running it is asked to open file. If the application is not running, then Windows starts the application for you.
So if the application is not already running and it is started for you it becomes associated with your program as a 'child' process. Therefore your System(..) call waits for it to end before continuing. If however Excel is already running then once Windows informs that instance of your desire to open the file test.xls, your call to System(..) returns immediately.
You can avoid this by explicitly running the Excel program by giving the full path to the Excel EXE file. And including the /x command line argument and full path to your file. The /x causes Excel to open a new process and then open your file. This new process is a child of your program's so the System(..) call will wait..
I'm not familiar with the System(..) call (is it like the system(..) one?) you may have to provide the switch /x, and path arguments as distinct arguments to this call rather than in one long string. Also there may be options on how your child process is launched, so waiting for it to return may be optional and so forth.
Related
This is kind of an odd question but does anyone know how to make a c++ program open multiple separate CMD prompts? they don't even have to be proper command prompts they can spit out text in a separate CMD like window that's fine. they don't need to talk to each other or do anything more than display text. the only reason I'm not doing this in Batch is because it needs to be a compiled EXE. I know I can run windows commands in c++ with "system(...)" however I'm not sure how to force these to be separate windows. if anyone knows a way to do that I would greatly appreciate it.
Thank you for your time
You can use CreateProcess to rum cmd,and communicate through pipe.
Your question is not clear to me, but let me try:
A single process can have no or exactly one console window. E.g. in Visual Studio, in the linker settings, you can set the subsystem to console, then the console window is opened automatically or you can use AllocConsole to get one. If you need more windows to display text, you have to create these windows by yourself (these windows aren't normal console windows). Another possibility is to start more backgroud processes, each having its own console window to display the text. To start these background processes, use CreateProcess and use for dwCreationFlags CREATE_NEW_CONSOLE.
If you have a batch file and want to display multiple console windows, use the start command to start your console program to create a new console and disply its output there, e.g.
start cmd.exe /k dir
I'm trying to figure out a way to open SAS programs in new instances of the Enhanced Editor by default on click.
The question has been asked before but no luck.
This paper describes the way a program is opened with the Enhanced Editor. The full command is :
"C:\PROGRA~1\SASHome\SASFOU~1\9.3\core\sasexe\SASOACT.EXE" action=Open
datatype=SASFile filename="%1" progid=SAS.Application.903
The author explains that:
The sasoact.exe program is used to launch an OLE automation session of SAS.
Automation
is a mechanism through
which one Windows application can control another application programmatically. When you double-click a SAS file
type, sasoact.exe checks to see if an existing OLE automation session of SAS is running. If not, it then invokes an
OLE automation session of SAS. Once there is an active
SAS automation server session, any further calls from
sasoact.exe are handled by the existing SAS session instead of in a new
SAS session.
I guess having only one OLE session is usefull in some way or another but it's really annoying when you have to manually open a new EE instance every time you want to run multiple jobs. Not to mention that sasoact targets the first session initiated and if a job is already running on that session well your program is not going to open.
Is there a way to directly request a new instance of the OLE session or perhaps "trick" sasoact.exe into not seeing the opened sessions ?
[EDIT] Well too bad it's been closed as duplicate because the answer is substantially different than the other question's. Also it might help others who do not want to run their programs from a batch file.
Here is the registry key that works:
"C:\Program Files\SAS\SASFoundation\9.2(32-bit)\sas.exe" -initstmt "dm 'whost;include ''%1'' ';"
I added it in HKEY_CLASSES_ROOT\SAS.Program.701\shell\Open New\command so now I have a neat little extra option in my drop-down menu that effectively opens programs in new sessions on click:
A similar thread showing the use of a batch file to open a SAS program in a new session is available here.
If you want to open a .sas program in a new session by simply clicking the program here is how to do it:
You have to add an entry to the registry. Be careful when messing around with registry files, always back up your entries.
Open the registry editor (WIN+R > regedit).
In the directory HKEY_CLASSES_ROOT\SAS.Program.701\shell\ create a sub-directory with a meaningful name(right-click on shell > New > Key). I named mine "Open New". In this new sub-directory create another sub named command. You should now have a path that looks like:
HKEY_CLASSES_ROOT\SAS.Program.701\shell\Open New\command
In here, right-click on the file on the registry file on the right > Modify and add the following in the Value data field (change the path of sas.exe if needed)
"C:\Program Files\SAS\SASFoundation\9.2(32-bit)\sas.exe" -NOTUTORIALDLG -initstmt "dm 'whost;include ''%1'' ';"
Close the editor. You should now have the new option specified in the drop-down menu of the right-click on a .sas program:
This option will open your program with the Enhanced Editor in a new SAS session.
Now if you want it to work for double-clicking I suppose you'd have to replace the value in the Open sub-directory with the one from above. I haven't done it and I don't recommend it, the extra option in the drop-down is enough for me.
I wish to use the functions of autohotkey within a C++ program.
I am currently running my scripts triggered by the c++ program- I just run them as a .bat file. This works well but the problem is that I cannot return values from the script to the c++ program.
I wish to be able to read the position of the mouse from the script and make decisions based upon this in my C++ program. My scripts do quite complex things- so doing this in autohotkey is the best solution for me- I have knowledge of C, but little of C++.
I have read about the Autohotkey .DLL - I know how to trigger it but not how to read values from it. If anyone could instruct me or even post example code of a .dll being loaded and a value sent to a script and a value returned- I would be eternally grateful!!
I have spent hours on this and to no avail!
to return a value, could this possibly work http://www.autohotkey.net/~tinku99/ahkdll/functions/ahkgetvar.htm
I'm not sure about the dll, but you could just write your own application in Autohotkey and package it along with your C++.
The communication takes place over a hidden window with an edit control and a button. You use one application to set text in the edit box, and then to click the submit button. The other application owns the window can process whatever is put into the edit control - as if you were passing a variable. Basically, that's it.
Check out this thread where I've explained it in more detail: How to send a command to a running application via commandline
Now, that's not quite what you wanted, but the effect is the same, and you already know all the api.
I'm trying to fulfill a client request here, and I'm not entirely sure I can actually do it. I have an MFC application that relies upon ShellExecute to open files in their appropriate viewer, which spawns multiple viewers if you try to open multiple files one after the other. If you open one .txt document, and then open another, two copies of notepad appear as expected.
The client wants us to change this functionality - Windows' functionality - to just pass file locations to any viewers that might already be opening. The first image clicked should open Image Viewer, but any other should just be opened in that existing process.
Is that kind of inter-application control/communication possible? Can I generically "pass" files to existing processes? I don't think I can. Executing a program with a file as a parameter is one thing, but passing a file to a running process is something else altogether. I'm not sure you can do that generically, I don't think that kind of functionality is anywhere in the Windows APIs.
I could be wrong, though.
This isn't possible if the viewer don't support multiple open files in same instance.
in your example: notepad will launch a new version with each file, while Notepad++ (a free editor) will open in same instance in a new tab.
The first thing you should try is calling the program again with the new parameters. If the program is written in such a way it will delegate the new parameter to the existing instance. Notepad doesn't do this, image viewer may though.
The next thing you can try is managing the life of the application by keeping track of the handle yourself. You call CreateProcess, so you create and own the handle to this process. On the next call to CreateProcess, enumerate the open windows and try to find your last handle. If the handle is found, close it and continue with your open process. You should only get one open application. For the most reliable solution, put this in a separate thread and wait for the handle (as well as a new request event) to avoid any race conditions.
I'm trying to make a small program that could intercept the open process of a file.
The purpose is when an user double-click on a file in a given folder, windows would inform to the software, then it process that petition and return windows the data of the file.
Maybe there would be another solution like monitoring Open messages and force Windows to wait while the program prepare the contents of the file.
One application of this concept, could be to manage desencryption of a file in a transparent way to the user.
In this context, the encrypted file would be on the disk and when the user open it ( with double-click on it or with some application such as notepad ), the background process would intercept that open event, desencrypt the file and give the contents of that file to the asking application.
It's a little bit strange concept, it could be like "Man In The Middle" network concept, but with files instead of network packets.
Thanks for reading.
The best way to do it to cover all cases of opening from any program would be via a file system filter driver. This may be too complex for your needs though.
You can use the trick that Process Explorer uses to replace itself with task manager. Basically create a key like this:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe
Where you replace 'taskmgr.exe' with the name of the process to intercept. Then add a string value called 'Debugger' that has the path to your executable. E.g:
Debugger -> "C:\windows\system32\notepad.exe"
Every a process is run that matches the image name your process will actually be called as a debugger for that process with the path to the actual process as an argument.
You could use code injection and API redirection. You'd start your target process and then inject a DLL which hooks the windows API functions that you want to intercept. You then get called when the target process thinks it's calling OpenFile() or whatever and you can do what you like before passing the call on to the real API.
Google for "IAT hooking".
Windows has an option to encrypt files on the disk (file->properties->advanced->encrypt) and this option is completely transparent to the applications.
Maybe to encrypt decrypt file portions of a disk you should consider softwares like criptainer?
There is this software as well http://www.truecrypt.org/downloads (free and open source) but I haven't tried it.
Developing a custom solution sounds very difficult.