If I use this in a cmd console
tasklist.exe /? > help.txt
it works of course
If I use this in an exefile
.data
exe_file db "C:\windows\system32\tasklist.exe",0
param1 db "/? > help.txt",0
sei SHELLEXECUTEINFO <?>
.code
mov esi,offset sei
xor eax,eax
mov SHELLEXECUTEINFO.cbSize[esi],SIZEOF SHELLEXECUTEINFO
mov SHELLEXECUTEINFO.fMask[esi], SEE_MASK_NOCLOSEPROCESS
mov SHELLEXECUTEINFO.hwnd[esi],eax
mov SHELLEXECUTEINFO.lpVerb[esi],offset fOpen
mov SHELLEXECUTEINFO.lpFile[esi],offset exe_file
mov SHELLEXECUTEINFO.lpParameters[esi],offset param1
mov SHELLEXECUTEINFO.lpDirectory[esi],eax
mov SHELLEXECUTEINFO.nShow[esi],SW_SHOWNORMA
mov SHELLEXECUTEINFO.hInstApp[esi],eax
INVOKE ShellExecuteEx,esi
It opens tasklist.exe (returns 1 ) but does not write the textfile
Where is the secret ?
piping belongs to console...
exe_file db "C:\windows\system32\cmd.exe",0
param1 db "/c tasklist.exe /? > help.txt",0
...
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
FileWrite "help1.txt", Launch$("C:\windows\system32\tasklist.exe /?")
Let esi=FileRead$("help1.txt")
PrintLine "Method A: [", Left$(esi, 200), "...] **", CrLf$, CrLf$
Launch Chr$("C:\windows\system32\cmd.exe /c tasklist.exe /? ", 62, " help2.txt")
Let esi=FileRead$("help2.txt")
PrintLine "Method B: [", Left$(esi, 200), "...] **"
EndOfCode
Method A: [
TASKLIST [/S sistema [/U nomeutente [/P [password]]]]
[/M [modulo] | /SVC | /V] [/FI filtro] [/FO formato] [/NH]
Descrizione:
Questo strumento visualizza un elenco dei processi in ...] **
Method B: [
TASKLIST [/S sistema [/U nomeutente [/P [password]]]]
[/M [modulo] | /SVC | /V] [/FI filtro] [/FO formato] [/NH]
Descrizione:
Questo strumento visualizza un elenco dei processi in ...] **
;)
TWell,
no - checked that out before. Using a computer since 1984 I am quite ok. with batch style files.
JJ, I check your code out
TWELL,
excuse me - your code works...
Thanks
TWELL thanks again,
my aim was to check if mysqld.exe is running.
There are various methods to do this.
This is the shortest and easiest.
.data
exe_file db "C:\windows\system32\cmd.exe",0
param1 db "/c tasklist.exe | FINDSTR mysqld.exe > mysql.txt",0
fOpen db "open",0
.code
start:
INVOKE ShellExecute,0,offset fOpen,offset exe_file,offset param1,NULL,SW_HIDE
INVOKE ExitProcess,0
end start
If mysql.txt is empty mysqld.exe does not run
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
.if Instr_(Launch$("tasklist.exe"), "svchost", 1)
Inkey "There is at least one svchost active"
.else
Inkey "Sorry, no svchost here"
.endif
EndOfCode
No file created. Replace svchost with mysqld.exe ...
Or just in RealBoy(tm) style#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
BOOL FindProc(TCHAR *pszExe)
{
HANDLE hSnapShot;
PROCESSENTRY32 pEntry;
BOOL bFound = FALSE;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot) {
pEntry.dwSize = sizeof(pEntry);
if (Process32First(hSnapShot, &pEntry)) {
do {
//wsprintf(szTmp, "%d %s", pEntry.th32ProcessID, pEntry.szExeFile);
if (!lstrcmp(pEntry.szExeFile, pszExe)) {
// found it
bFound = TRUE;
break;
}
} while (Process32Next(hSnapShot, &pEntry));
}
CloseHandle(hSnapShot);
}
return bFound;
}
void __cdecl WinMainCRTStartup(void)
{
if (FindProc(TEXT("explorer.exe")))
MessageBox(0,TEXT("Found explorer.exe"),0,MB_OK);
ExitProcess(0);
}
:t
With your original question, write the data to a batch file then run the batch file. Easy to do and it always works.
One more option:
include \masm32\MasmBasic\MasmBasic.inc
Init
mov ecx, GetProcessArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1361)(?)
.Repeat
dec ecx
.Break .if Sign?
.Until Instr_(MbProc$(ecx), "\Explorer.exe", 1)
.if Sign?
Inkey "Explorer not found"
.else
Inkey "Process found: ", MbProc$(ecx)
.endif
EndOfCode
Tested with the Cygwin terminal :
$ tasklist | grep explorer.exe
explorer.exe 688 Console 0 44.884 K
Quote from: TWell on February 02, 2017, 07:59:27 AM
Or just in RealBoy(tm) style
Let's round it out with the Puts-hairs-on-your-chest-Real-Men(TM) method in C++ & WMI :P
Just so I'm not reiterating things above, and to make it maybe a bit useful, this also includes how to be notified of new and ending processes without manually checking for them yourself. That functionality requires running the program as admin though. There is a method that doesn't require admin, but I haven't done it this way before so I chose this over that.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <ole2.h>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#define CHECK_HR_AND_RETURN(x) \
if(FAILED(hr = (x))) \
{ \
printf(#x " failed with hr=%x\n", hr); \
return 1; \
}
#define CHECK_HR(x) \
if(FAILED(hr = (x))) \
{ \
printf(#x " failed with hr=%x\n", hr); \
}
#define CONCAT_INT(a, b) a##b
#define CONCAT(a, b) CONCAT_INT(a, b)
#define STACK_BSTR(contents, varName) \
struct CONCAT(StackBStr, __COUNTER__) \
{ \
ULONG bstrSize; \
WCHAR text[sizeof(contents) / sizeof(WCHAR)]; \
operator BSTR() {return text;} \
} varName = {sizeof(contents), contents}
class ProcessNotifier : public IWbemObjectSink
{
STDMETHOD(QueryInterface)(REFIID iid, PVOID* ppv)
{
*ppv = NULL;
if(iid == IID_IUnknown || iid == IID_IWbemObjectSink)
{
AddRef();
*ppv = this;
}
return *ppv ? S_OK : E_NOINTERFACE;
}
// Implement proper ref counting if using for more than this
STDMETHOD_(ULONG, AddRef) () { return 1; }
STDMETHOD_(ULONG, Release) () { return 1; }
STDMETHOD(Indicate)(long numObjs, IWbemClassObject** ppObjs)
{
if(numObjs == 0 || ppObjs == NULL) return WBEM_E_INVALID_PARAMETER;
for(long i = 0; i < numObjs; ++i)
{
if(IWbemClassObject* pProc = ppObjs[i])
{
HRESULT hr;
VARIANT vName = {VT_EMPTY}, vCmdLine = {VT_EMPTY}, vPid = {VT_EMPTY};
CIMTYPE type;
hr = pProc->Get(L"Name", 0, &vName, &type, NULL);
hr = pProc->Get(L"CommandLine", 0, &vCmdLine, &type, NULL);
hr = pProc->Get(L"ProcessId", 0, &vPid, &type, NULL);
printf("Found existing pid %lu, %ws (%ws)\n", V_UI4(&vPid), V_BSTR(&vName), V_BSTR(&vCmdLine));
VariantClear(&vName);
VariantClear(&vCmdLine);
VariantClear(&vPid);
}
}
return WBEM_S_NO_ERROR;
}
STDMETHOD(SetStatus)(long, HRESULT hr, BSTR param, IWbemClassObject*)
{
if(hr == WBEM_E_CALL_CANCELLED)
{
puts("Ending notifications for process enum");
}
else if(hr != WBEM_S_NO_ERROR)
{
printf(__FUNCTION__ " called with param=%ws, hr=%#08x\n", param, hr);
}
return WBEM_S_NO_ERROR;
}
};
class ProcessChangeNotifier : public ProcessNotifier
{
IWbemServices* pServices;
public:
ProcessChangeNotifier(IWbemServices* pSvc) : pServices(pSvc) {}
STDMETHOD(Indicate)(long numObjs, IWbemClassObject** ppObjs)
{
if(numObjs == 0 || ppObjs == NULL) return WBEM_E_INVALID_PARAMETER;
// offset to --- is hardcoded below, change that if changing this
// have to use Handle (aka the PID) to find the process, since it's
// the 'key property', whatever that means
STACK_BSTR(L"Win32_Process.Handle=\"------------", parentPath);
for(long i = 0; i < numObjs; ++i)
{
if(IWbemClassObject* pProc = ppObjs[i])
{
HRESULT hr, hrExitCode;
VARIANT vName, vPid, vExitCode;
CIMTYPE type;
hrExitCode = pProc->Get(L"ExitStatus", 0, &vExitCode, &type, NULL);
hr = pProc->Get(L"ProcessName", 0, &vName, &type, NULL);
hr = pProc->Get(L"ProcessId", 0, &vPid, &type, NULL);
if(SUCCEEDED(hrExitCode))
{
// this is a stopped process
printf("Process %ws (PID %lu) exited with code %lu\n", V_BSTR(&vName), V_UI4(&vPid), V_UI4(&vExitCode));
VariantClear(&vExitCode);
}
else
{
// this is a created process
VARIANT vParentId, vParentName = {VT_EMPTY};
hr = pProc->Get(L"ParentProcessID", 0, &vParentId, &type, NULL);
_snwprintf(parentPath.text + 22, 11, L"%lu\"", V_UI4(&vParentId));
IWbemClassObject* pParentProcess = NULL;
// apparently calling into WMI from Indicate is bad, I don't care
if(SUCCEEDED(hr = pServices->GetObject(parentPath, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pParentProcess, NULL)))
{
hr = pParentProcess->Get(L"Name", 0, &vParentName, &type, NULL);
pParentProcess->Release();
}
PCWSTR pParentName = (V_VT(&vParentName) == VT_BSTR) ? V_BSTR(&vParentName) : L"Unknown";
printf("Process %ws (%lu) created by process %ws\n", V_BSTR(&vName), V_UI4(&vPid), pParentName);
VariantClear(&vParentName);
VariantClear(&vParentId);
}
VariantClear(&vName);
VariantClear(&vPid);
}
}
return WBEM_S_NO_ERROR;
}
STDMETHOD(SetStatus)(long, HRESULT hr, BSTR param, IWbemClassObject*)
{
if(hr == WBEM_E_CALL_CANCELLED)
{
puts("Ending process start/stop notifications");
}
else if(hr != WBEM_S_NO_ERROR)
{
printf(__FUNCTION__ " called with param=%ws, hr=%#08x\n", param, hr);
}
return WBEM_S_NO_ERROR;
}
};
int __cdecl main(int, char**)
{
HRESULT hr;
CHECK_HR_AND_RETURN(CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE));
CHECK_HR_AND_RETURN(
CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_DISABLE_AAA,
NULL
)
);
IWbemLocator* pLocator = NULL;
CHECK_HR_AND_RETURN(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pLocator)));
STACK_BSTR(L"root\\cimv2", cimName);
IWbemServices* pNamespace = NULL;
CHECK_HR_AND_RETURN(pLocator->ConnectServer(cimName, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace));
pLocator->Release();
CHECK_HR_AND_RETURN(CoSetProxyBlanket(pNamespace, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE));
STACK_BSTR(L"WQL", wql);
STACK_BSTR(L"SELECT * From Win32_Process", processQuery);
STACK_BSTR(L"SELECT * From Win32_ProcessStartTrace", newProcessQuery);
STACK_BSTR(L"SELECT * From Win32_ProcessStopTrace", deadProcessQuery);
ProcessNotifier procNotifier;
CHECK_HR_AND_RETURN(pNamespace->ExecQueryAsync(wql, processQuery, 0, NULL, &procNotifier));
ProcessChangeNotifier newProcNotifier(pNamespace);
// these two will fail with WBEM_E_ACCESS_DENIED unless running as admin
CHECK_HR(pNamespace->ExecNotificationQueryAsync(wql, newProcessQuery, 0, NULL, &newProcNotifier));
CHECK_HR(pNamespace->ExecNotificationQueryAsync(wql, deadProcessQuery, 0, NULL, &newProcNotifier));
puts("Press enter to exit");
getchar();
pNamespace->CancelAsyncCall(&newProcNotifier);
pNamespace->CancelAsyncCall(&procNotifier);
pNamespace->Release();
CoUninitialize();
}
Quote from: adeyblue on February 04, 2017, 06:06:55 AMLet's round it out with the Puts-hairs-on-your-chest-Real-Men(TM) method in C++ & WMI :P
Just so I'm not reiterating things above, and to make it maybe a bit useful, this also includes how to be notified of new and ending processes without manually checking for them yourself.
Great code :t
In the meantime, I've implemented a lean-and-mean FindProcess() macro based on Tim's example, see here (http://masm32.com/board/index.php?topic=94.msg63598#msg63598).