I have a Windows service written in C++ that needs to access the clipboard and read data from/paste data to it. I'm considering only textual data.
From MSDN's documentation, I can use OpenClipboard, EmptyClipboard and SetClipboardData to achieve what I want to.
I would have to pass NULL to OpenClipboard since I don't have any UI and hence no window handles. However, this would mean -
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.
which would mean I can't set data on the clipboard.
What would be the correct way to get around this problem? Is it possible without using any windows?
You definitely CAN access the clipboard from a non-GUI application. Windows even included a command-line app (clip.exe) to do it.
However, before you spend too much time working on this......
The clipboard isn't shared among users on the same system. Suppose you have two users logged in. You can't copy data from one session, switch users (from the lock screen) and paste that same data.
So presumably, your service would act like another user session, and your app would only be able to see data that was copied earlier within that same instance of the service.
Related
I have a c++ exe program I do not own the source and I want to access some data which is in the ListView. Is there any way to do this?
(My best guess is using memory address but how to know the format of ListView)
Image of the program
You can access ListView data by sending LVM_ messages to it if it owns data.
Or if ListView is virtual, data is provided by LVN_ notifications by its parent window. Either way, you need to be in exe's address space, so you would have to inject own code (which can be achived by making that exe load your DLL, can be done by windows hooks or by CreateRemoteThread).
So, generally it is possible, but cumbersome.
My app needs to write and maintain a log file and its not running in admin mode. My question is what path could my app write to in such a situation. How could I obtain that path ?
There are two good options:
Use the Windows Event Log. You can easily create your own log for your application (if you expect to generate a lot of messages), or you can just add the messages to the standard logs (if you expect to generate only a few, occasional messages).
Since this is a built-in feature, any technical person is going to know about it and be able to locate your log files easily. It's also very interoperable with centralized management systems.
Write to a text file saved in the Application Data directory. This is where applications are supposed to store non-user data files, since, as you mentioned, the application directory is not something you can assume write privileges to.
For a log file about stuff that is specific to a particular computer, I'd say that this is local (non-roaming) application data, so you want the Local App Data folder. I'm sure that there is a Qt wrapper for this, but in Win32, you would call the SHGetKnownFolderPath function, specifying the KNOWNFOLDERID value FOLDERID_LocalAppData.
Remember that this function allocates memory to store the returned string—you must free it with a call to CoTaskMemFree when you are finished.
Sample code:
// Retrieve the path to the local App Data folder.
wchar_t* pszPath = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pszPath);
// Make a copy of that path.
std::wstring path(pszPath);
// Free the memory now, so you don't forget!
CoTaskMemFree(static_cast<void*>(pszPath));
Refer to the SHGetKnownFolderPath API, probably using the FOLDERID_LocalAppData option.
I want to retrieve a GUI Object so that I can read and modify they Object.
Right now the only way I can think of to do this is via injection (where the injection does a lot of the retrieving of the data and sends back what I want). My problem with injection is that I cannot easily debug it and it takes a long time to figure out what to do.
I can find the handle of the GUI object so is there a way i can use ReadProcessMemory() or something like this so that I can read the memory in another process and from this build it up into the GUI object that I want?
Assuming you have the proper permissions and have some way to obtain the window handle (HWND) of a specific GUI object (see FindWindow()), you can call regular Win32 API functions such as SetWindowText() to modify the contents of those GUI objects.
However, doing this can break the other process' logic! If the process that owns the GUI object has cached some information and you modify the source behind its back, you might not get the desired effect.
I am embedding the ESRI Map Control into a custom ActiveX control written in MFC/C++. The custom ActiveX control serves as a Map Control wrapper so I can embed it into a specific environment that is runtime only and non-relational. Thanks to this site, I am able to load feature points into an in-memory workspace. However, the hosting environment now gets stuck in memory when closed, and it only does this when I am using the InMemoryWorkspaceFactory. My conclusion, therefore, is that the factory has locked a file or resource and, by not releasing it, is causing the host environment to never close.
Is there a way I can manually delete all features and feature classes during my ActiveX control's WM_DESTROY message and release the workspace completely? There doesn't seem to be a counterpart to the IWorkspaceFactory's Create method. My code is releasing all interfaces to the workspace factory, but apparently there are still references internally in ArcObjects.
I discovered the answer to my question. It wasn't the in-memory workspace that needed to be closed, it was ArcObjects in general. The solution is to make sure to call the Shutdown method of the IAoInitialize interface during the WM_DESTROY message.
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.