|
Hi all.
I have a application writen in VC++. I need to execute a script file on a server in it. Did any one know how to do it?
Thanks for any clue.
Tida
|
|
|
|
|
What kind of script file... like an NT command script, or ??
If all you need to do is execute a cmd script remotely, you can do that without any code. Look at soon.exe in the NT reskit, which will let you execute cmd scripts on remote servers.
Otherwise, via C++ you can launch a cmd script like this:
ShellExecute( NULL, "open", "c:\\my_script.cmd", NULL, "c:\\", SW_SHOWNORMAL );
Take a look at MSDN for descriptions of the parameters to ShellExecute.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Does anybody have a sample or idea about how to get image in coordinates of the mouse pointer ?
thank you !
|
|
|
|
|
Hi, I've got a VC6.0 project, and I exported a MAK file for it using VStudio. I want to MAKE the project using the MINGW (Minimalist GNU for Win32) package. Is it possible to use the MAK file that VStudio creates and pass it on to mingw32-make.exe somehow?
/=/=/=/=
Deus
/=/=/=/=
|
|
|
|
|
You can import the .dsp to create an MINGW project. I haven't got MINGW at work so I can't tell you exactly what the menu are, but it's under File - Import(maybe)
NB! If you're using MFC then you're out of luck!
Mike Eriksson
Sonork 100.21825
|
|
|
|
|
Is there a maxsize limit I can specify on a STL queue container? I seem to remember that some of the other container objects had a maxsize attribute or function to set the size.
I've done some searching on the web and couldn't find anything relevant.
A second question. If there is a maxsize limit, when I do a push() onto the queue, what kind of error will it generate to let me know that it is already full?
Ok, people may be wondering why I need a maxsize limit. I have an object that displays data onscreen that will update with new data on a timer event. The data will be put into a queue. I am also recording the data (rcvd from network) to disk - high priority, and displaying statistics (lower priority) and displaying the data (lower priority). If the data to be displayed gets too old (e.g. the queue is full), I want to display a status message.
|
|
|
|
|
There isn't a max_size limit. There is a max_size() function in the vector and list containers, but they are merely measurements of how many actual elements you can store; it's not something you can purposefully set.
My suggestion would be to check the current size (via the size() method) of the queue before doing a push. If it's already at your maximum size, do your error code there and skip the push.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Yeah, that's what I figured. I guess I could subclass queue and override the push method.
BTW, I thought the max_size function was not the amt of items currently stored, I thought it was size() that returned that and max_size returned the max limit of what you could store.
|
|
|
|
|
Correct; max_size() is the number of elements that can be stored, and never changes regardless of insertions or deletions. size() is the number of elements currently stored, and of course changes with every insert and delete.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Greetings,
I need to get an HWND but all I have is an HINSTANCE. There must be some simple way to make the conversion but my brain is blocked. This can't be that difficult!
What I am doing is using ShellExecuteEx() to open up a PDF file. I then want to send keyboard messages to this new process to make it go to Page XXX.
(Yes, I know that if I had the full Acrobat I could do this with OLE or even DDE. But I don't. And the alleged pdf ActiveX control is only intended to work within a browser. Sigh...)
I need to be able to take the hProcess field from the SHELLEXECUTEINFO, as filled in by ShellExecuteEx(), and use it to wait for the new process to stabilize and then send the appropriate WM_KEYDOWN and WM_CHAR messages.
Failing that, I would like to be able to enumerate all the windows and find the one corresponding to the one I spawned. I am looking for a general solution rather than looking for a window containing "Acrobat Reader" in its title bar.
Can anybody give me a clue?
Thanks a lot!
void CIOGuidesView::OnButton1()
{
CString filename("PDF Files\\751018a.pdf");
HANDLE hProcess = NULL;
SHELLEXECUTEINFO shellInfo;
::ZeroMemory(&shellInfo, sizeof(shellInfo));
shellInfo.cbSize = sizeof(shellInfo);
shellInfo.lpVerb = "open";
shellInfo.lpFile = filename;
shellInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
if(::ShellExecuteEx(&shellInfo))
{
hProcess = shellInfo.hProcess;
}
else
{
ShowLastError("ShellExecuteEx Failed");
return;
}
int reason = WaitForInputIdle(hProcess,INFINITE);
switch(reason)
{
case 0:
MessageBox("subprocess now accepting user input");
break;
case WAIT_TIMEOUT:
MessageBox("Wait timeout");
break;
case 0xFFFFFFFF:
ShowLastError("WaitForInputIdle Failure");
break;
}
char title[1000];
::GetWindowText((HWND)hProcess,title,sizeof(title));
MessageBox(title,"Subprocess Window Title");
}
|
|
|
|
|
Casting hProcess to an HWND will certainly not do what you want.
You may need to EnumWindows and examine each one somehow to see if it's the one you want. I can't think of a way to get a process handle or a process id from a window handle but there must be a way. Then for each window handle EnumWindows gives you you could just see if it belongs to the process you just started. Simple!
The opinions expressed in this communication do not necessarily represent those of the author (especially if you find them impolite, discourteous or inflammatory).
|
|
|
|
|
GetWindowThreadProcessId will give you the process ID/thread ID of the process/thread that created the window handle.
Chris Richardson
|
|
|
|
|
Chris,
Well, I tried enumerating all the windows and using GetWindowThreadProcessId() and it doesn't seem to give me the same process id as obtained from the SHELLEXECUTEINFO structure (updated by ShellExecuteEx()):
The enumeration callback:
class WININFO
{
public:
CWnd *hWnd;
HINSTANCE hInst;
CString title;
WININFO(CWnd *wnd = NULL, HINSTANCE inst = NULL) {hWnd = wnd; hInst = inst; title = "";}
};
typedef CArray<WININFO,WININFO> CArrayWinInfo;
BOOL CALLBACK CIOGuidesView::enumwndfn(HWND hWnd, LPARAM lParam)
{
CIOGuidesView *me = (CIOGuidesView *)lParam;
return me->enumwndfn(CWnd::FromHandle(hWnd));
}
BOOL CIOGuidesView::enumwndfn(CWnd * wnd)
{
WININFO wininfo(wnd);
wnd->GetWindowText(wininfo.title);
DWORD ProcessId;
GetWindowThreadProcessId (wnd->GetSafeHwnd(), &ProcessId );
wininfo.hInst = (HINSTANCE)ProcessId;
m_WinInfoArray.Add(wininfo);
return TRUE;
}
The ShellExecuteEx() call:
void CIOGuidesView::OnButton1()
{
CString filename("PDF Files\\751018a.pdf");
HANDLE hProcess = NULL;
SHELLEXECUTEINFO shellInfo;
::ZeroMemory(&shellInfo, sizeof(shellInfo));
shellInfo.cbSize = sizeof(shellInfo);
shellInfo.lpVerb = "open";
shellInfo.lpFile = filename;
shellInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
if(::ShellExecuteEx(&shellInfo))
{
hProcess = shellInfo.hProcess;
}
else
{
ShowLastError("ShellExecuteEx Failed");
return;
}
int reason = WaitForInputIdle(hProcess,INFINITE);
And then I dumped all the windows whose title began with "Acro" OR those whose hInst matched my hProcess:
hProcess=0x01D8 hInst=0x045C title='Acrobat Reader'
If I understand this, the hProcess and hInst values should have been identical.
Ideas?
|
|
|
|
|
The HINSTANCE is not the same as the ID of the process. What you need to do, is use the ID of the process to get a handle to the process, which can be compared directly to the hProcess member of SHELLEXECUTEEX. Something like this:
BOOL CIOGuidesView::enumwndfn(CWnd * wnd)
{
WININFO wininfo(wnd);
wnd->GetWindowText(wininfo.title);
DWORD ProcessId;
GetWindowThreadProcessId (wnd->GetSafeHwnd(), &ProcessId );
HANDLE a_hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, ProcessID );
wininfo.hInst = (HINSTANCE)a_hProcess;
m_WinInfoArray.Add(wininfo);
return TRUE;
}
Chris Richardson
|
|
|
|
|
Chris Richardson wrote:
Why not close it immediately? Once you got the handle all you need it its value to use for comparison, you don't need to do anything else with it.
The opinions expressed in this communication do not necessarily represent those of the author (especially if you find them impolite, discourteous or inflammatory).
|
|
|
|
|
Whoops. I guess I had a momentary lapse of brain activity .
Chris Richardson
|
|
|
|
|
Chris,
I suspected I was mixing apples and oranges. But it still doesn't seem to work.
BOOL CIOGuidesView::enumwndfn(CWnd * wnd)
{
WININFO wininfo(wnd);
wnd->GetWindowText(wininfo.title);
DWORD ProcessId;
GetWindowThreadProcessId (wnd->GetSafeHwnd(), &ProcessId );
HANDLE a_hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, ProcessId );
wininfo.hInst = (HINSTANCE)a_hProcess;
CloseHandle(a_hProcess);
m_WinInfoArray.Add(wininfo);
return TRUE;
}
This still yields no exact matches on hProcess (from ShellExecuteEx) and a_hProcess (from OpenProcess).
I am beginning to wonder if AcroRd32.exe does something especially weird. I'll try something with another type of file...
I appreciate you looking at this. It has me bamboozled!
|
|
|
|
|
It seems that on my machine, OpenProcess is always returning the same value, no matter which ID you give it. That's pretty strange, but there's another way to do this. You could use CreateProcess, instead of ShellExecuteEx. CreateProcess will give you the ID of the process as well as it's handle, so you could directly compare the process ID gotten from GetWindowThreadProcessId with the process ID returned in the PROCESS_INFORMATION struct (from CreateProcess). I'll mess with this approach for a little while longer, and if I can get it to work, I'll let you know.
Chris Richardson
|
|
|
|
|
Chris,
I was just about to post a message here saying pretty much the same thing: OpenProcess() is giving the same value for different windows. I checked that they were truly different processes via the Task Manager.
I was hoping to avoid CreateProcess() as I like the idea of ShellExecuteEx()'s looking up the default program based on the file type. So I just use an lpVerb of "open" and the lpFile points to the .pdf file and ShellExecuteEx() takes care of everything else.
I suppose I can write the code to search the registry and duplicate this but it doesn't sound fun.
I don't suppose CreateProcess() does this kind of thing, does it?
|
|
|
|
|
CreateProcess won't do it for you, but you can use a function called SHGetFileInfo to get the exe path for you. Take a look at the SHGFI_ICONLOCATION flag of that function. It will get you the path to the .exe file containing the icon for the passed in .pdf file. Almost assuredly Acrobat Reader stores it's icon inside it's exe file, but this could be verified. If this sounds a little hackish and risky, then the registry stuff isn't all that bad anyways.
Good luck with it,
Chris Richardson
|
|
|
|
|
You might find the FindExecutable function useful.
|
|
|
|
|
OK, thanks to all you folks giving me help, I think I have it.
I now use FindExecutable() to get the default program, then CreateProcess() to spawn it:
char *filename = "C:\\src\\IOGuides\\PDF Files\\751018a.pdf";
TCHAR szExe[MAX_PATH];
::FindExecutable(filename, _T(""), szExe);
HANDLE hProcess = NULL;
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
::ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
::ZeroMemory(&processInfo, sizeof(processInfo));
char cmd[MAX_PATH + MAX_PATH + 5];
sprintf(cmd,"\"%s\" \"%s\"", szExe, filename);
BOOL startedOK = CreateProcess(
NULL,
cmd,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupInfo,
&processInfo);
if(!startedOK)
{
ShowLastError(filename);
return;
}
hProcess = processInfo.hProcess;
WaitForInputIdle(hProcess,INFINITE);
I then get the process ID from processInfo.dwProcessId and enumerate all the windows, using GetWindowThreadProcessId() to get the associated process ID.
BOOL CIOGuidesView::enumwndfn(CWnd * wnd)
{
WININFO wininfo(wnd);
wnd->GetWindowText(wininfo.title);
DWORD ProcessId;
GetWindowThreadProcessId (wnd->GetSafeHwnd(), &ProcessId );
wininfo.Pid = ProcessId;
m_WinInfoArray.Add(wininfo);
return TRUE;
}
Comparing processInfo.dwProcessId against the value from GetWindowThreadProcessId() gives me the match-up I needed.
Unfortunately, AcroRd32.exe is cutesy and allows only one instance to run at a time. If I already have the Reader running, the new process just closes down. Presumably after talking to its counterpart and giving the new filename.
Sigh.
I guess I can kill the old one first, but that won't alway work if the user manually started up AcroRd32.
Thanks for all your help. I'll probably make a "beginner" level article showing all of this in the next few weeks since doing this is not so obvious. I suspect the trick in making the article will be coming up with keywords and phrases to allow people to find it when they are looking to do this kind of thing. All the information I needed was in the articles; I just couldn't find it.
Again, many thanks for all of your patience and help. Now my one-day project (now in its fourth day) can be completed.
|
|
|
|
|
I feel like I should know this question, but it seems to me to be harder than I want it too.
Preface: I am working on a windows GUI interface for a embedded system. My boss wants to save off the current state of the system in to a file. However he has laid some requirements on the file format 1) it should be hand editable, 2) other applications should be able to open it, and 3) we don't need to rely on the having an outside application. My boss understands enough about software to be annoying and he is insisting that the file save be ODBC, however I admit I am not familiar enough with it. I do realize that you need to register a datasource and I am not sure how to do this on a different machine. My predecessor wrote the GUI in VB and he saved the file in Access format which was not hand editable.
I have cruised the site here and found some nice demonstrations. I had orginally thought that I would save the file in an Excel format. I noticed it used ODBC and my boss would be pleased. However I began to be concerned that it might fail on machines that don't have excel. We cannot require installation of Excel on a machine to run our GUI.
I think automation solutions I found on Microsofts site will also have this problem. I am not sure how the orginal VB code got around this problem with the Access format file using type libraries. (Not real familiar with those either.)
Does anyone have any advice on what to do and where to find documentation on doing it? I mean I can use ODBC if I can find a way to automate the registration of the data source.. but I need to brush up on this stuff again..
Thanks for any help,
Brian
If you start a fire for a man, he will be warm for a day. If you start that same man on fire, he will be warm for the rest of his life.
|
|
|
|
|
I seem to recall seeing a recent article that addressed creating a .XLS file even if there wasn't an ODBC driver for Excel installed. However, all I can find was the following:
http://www.codeproject.com/database/excel_odbc_write.asp
Try that other site, codeguru.com, too.
|
|
|
|
|
Thanks for the suggestion, but I checked out the "other site" and the articles on Excel. They all require excel ODBC drivers to read and write files.
I need to learn how to automated create ODBC or DAO drivers. I just need a method of letting others use additional software to edit the file outside of the actual GUI program.
I will keep looking...
Brian
If you start a fire for a man, he will be warm for a day. If you start that same man on fire, he will be warm for the rest of his life.
|
|
|
|
|