Jump to content

someone

Active Members
  • Posts

    552
  • Joined

  • Last visited

  • Days Won

    1

someone last won the day on February 9 2012

someone had the most liked content!

About someone

  • Birthday 06/01/1983

Profile Information

  • Member Title
    Reformed Mass Spammer!
  • Location
    Somerset NJ

someone's Achievements

  1. Hey doudou, Thanks a lot for the response. Funny I haven't been on the forums regularly in a while and just happened to stop in the last week or so. I ended up going a different route, to be honest I have to revisit what didn't work and put it into context of what you said to see if that helps me get anywhere. In case anyone runs into the same thing, I was trying to automate a BMC Remedy Macro where you need to supply arguments. So say I setup a macro to look for a ticket # based on a client name, you are supposed to be able to run the macro and give it John Doe and have it silently run the macro. The DDE interface for Remedy is deprecated but everything I read and tried seems they broke the COM interface for this function. I can run macros that do not require parameters, but not anything with. Turns out someone at work had a working DDE C++ code, so I stole adopted that and it did work...except there was a character limit, and its really low. I couldn't run half the macros I wanted. So I ended up with 2 different workarounds...I'm just automating the keystrokes to run the macro against the Remedy window (which actually works ALOT better then I thought that it would). Back to using a COM wrapper created to provide better functionality then what BMC offers.
  2. Jos how are you so fast? Just went to say yes its a 32/64 bit issue... if you compile your exe as 64 and run it it will likely work without problem. Its always a good tip when doing DOS commands put /k to see what is happening...so RunWait(@ComSpec & " /k " & $CommandFinal , "", @SW_SHOW)
  3. I redid the code so I could lean better to help figure out what is going wrong. There were a few errors (the structs had incompatible autoit data types, etc). Here is the code I have now, there are 2 problems I have I can't figure out... Right now I am trying only .Net 4 Line 100: _WinAPI_WaitForMultipleObjects isn't continuing (it always reaches the timeout, -1 makes it hang indefinitely Line 117: DllStructGetData($tMMIOData, 'm_installProgressSoFar') is giving me @error = 2. I put tons of message boxes and a few tooltips in the code to help me. This is the link to the C++ code I am trying to replicate. #include <WinAPI.au3> #include <WinAPIFiles.au3> #include <WinAPIProc.au3> #include <Array.au3> Global $__DotNetSetup_sSection = 0 Global $__DotNetSetup_hSection = 0 Global $__DotNetSetup_pSection = 0 Global $__DotNetSetup_hEventIn = 0 Global $__DotNetSetup_hEventOut = 0 Global $__DotNetSetup_sSection = "dotnet4sectionname" Global $__DotNetSetup_sEvent = "dotnet4eventname" Const $MAX_PATH = 255 Const $tagMMIODATA_V4_0 = 'BOOL m_downloadFinished;' & _ ;Is download complete? 'BOOL m_installFinished;' & _ ;Is installation complete? 'BOOL m_downloadAbort;' & _ ;Set to cause downloader to abort. 'BOOL m_installAbort;' & _ ;Set to cause installer to abort. 'LONG m_hrDownloadFinished;' & _ ;Resulting HRESULT for download. 'LONG m_hrInstallFinished;' & _ ;Resulting HRESULT for installation. 'LONG m_hrInternalError;' & _ 'WCHAR m_szCurrentItemStep[' & $MAX_PATH & '];' & _ 'char m_downloadSoFar;' & _ ;Download progress 0-255 (0-100% done). 'char m_installSoFar;' & _ ;Installation progress 0-255 (0-100% done). 'WCHAR m_szEventName[' & $MAX_PATH & '];' ;Event that chainer creates and chainee opens to sync communications. Global $tagMMIODATA = $tagMMIODATA_V4_0 $reg = _DotNetSetup_Register($__DotNetSetup_sEvent, $__DotNetSetup_sSection) MsgBox(0, "reg", "return=" & $reg & ", " & @error & ", " & @extended) _start() Func _start() If Not($__DotNetSetup_hSection And $__DotNetSetup_pSection _ And $__DotNetSetup_hEventIn) Then Return SetError(1, 0, 0) Local $tMMIOData = DllStructCreate($tagMMIODATA, $__DotNetSetup_pSection) If @error Then MsgBox(0, "$tMMIOData error", "error: " & @error) Exit Else MsgBox(0, "no $tMMIOData error", DllStructGetSize($tMMIOData)) EndIf Local $tWaitHandles = DllStructCreate('HANDLE;HANDLE') If @error Then MsgBox(0, "$tWaitHandles error", "error: " & @error) Exit Else MsgBox(0, "no $tWaitHandles error", DllStructGetSize($tWaitHandles)) EndIf ;Start the setup process and get information (handle to the setup thread and process) $sAppPath = @ScriptDir & '\dotNetFx40_Full_x86_x64.exe' Local $sNetSetupAppPath = $sAppPath & ' /pipe ' & $__DotNetSetup_sSection ;-pipe? or /pipe Local $tStartupInfo = DllStructCreate($tagSTARTUPINFO) If @error Then MsgBox(0, "$tStartupInfo error", "error: " & @error) Exit Else MsgBox(0, "no $tStartupInfo error", DllStructGetSize($tStartupInfo)) EndIf Local $tProcessInfo = DllStructCreate($tagPROCESS_INFORMATION) If @error Then MsgBox(0, "$tProcessInfo error", "error: " & @error) Exit Else MsgBox(0, "no $tProcessInfo error", DllStructGetSize($tProcessInfo)) EndIf If (Not _WinAPI_CreateProcess('', $sNetSetupAppPath, 0, 0, False, 0, 0, '', DllStructGetPtr($tStartupInfo), DllStructGetPtr($tProcessInfo))) Then MsgBox(0, "", "can't start") ; Cannot start the setup process. Return SetError(1000, _WinAPI_GetLastError(), False) EndIf ;;;;up to here Local $hThread = DllStructGetData($tProcessInfo, 'hThread') Local $hProcess = DllStructGetData($tProcessInfo, 'hProcess') MsgBox(0, "$hThread", $hThread) MsgBox(0, "$hProcess", $hProcess) ; Assign wait handles: to setup process, DllStructSetData($tWaitHandles, 1, $hProcess) If @error Then MsgBox(0, "$tWaitHandles error", "$tWaitHandles $hProcess struct setdata error") ; and to the event object DllStructSetData($tWaitHandles, 2, $__DotNetSetup_hEventIn) If @error Then MsgBox(0, "$tWaitHandles error", "$tWaitHandles $__DotNetSetup_hEventIn struct setdata error") MsgBox(0, DllStructGetPtr($tWaitHandles), "about to go into while") ;~ MsgBox(0, "", $__DotNetSetup_hEventIn) ;~ _WinAPI_WaitForSingleObject($hProcess, -1) ;~ MsgBox(0, "", "wait over") While Not __DotNetSetup_IsDone() ;MsgBox(0, "should be 0 until done", __DotNetSetup_IsDone()) Sleep(5000) Local $dwRet = _WinAPI_WaitForMultipleObjects(2, DllStructGetPtr($tWaitHandles), False, 100) If $dwRet = -1 Then MsgBox(0, "WinAPI", _WinAPI_GetLastError()) ToolTip($dwRet) Switch $dwRet Case 0 ;closed MsgBox(0, "", "dotnet closed") ExitLoop EndSwitch __DotNetSetup_GetProgress() WEnd EndFunc Func __DotNetSetup_GetProgress($bTotal = False) Local $tMMIOData = DllStructCreate($tagMMIODATA, $__DotNetSetup_pSection) Local $nDownloadProgress = DllStructGetData($tMMIOData, 'm_downloadProgressSoFar') Local $nInstallProgress = DllStructGetData($tMMIOData, 'm_installProgressSoFar') MsgBox(0, "$nInstallProgress", $nInstallProgress & " @error = " & @error) ;getting error 2 - Element out of range or unknown. If ($bTotal) Then Return ($nDownloadProgress + $nInstallProgress) / 2 Else Local $aRet[2] = [$nDownloadProgress, $nInstallProgress] Return $aRet EndIf EndFunc Func __DotNetSetup_IsDone() Local $tMMIOData = DllStructCreate($tagMMIODATA, $__DotNetSetup_pSection) ;~ Return DllStructGetData($tMMIOData, 'm_downloadFinished') And DllStructGetData($tMMIOData, 'm_installFinished') Return DllStructGetData($tMMIOData, 'm_installFinished') ;just returning (0/1) for installfinished EndFunc Func _DotNetSetup_Register($sSectionName, $sEventName) ; Fails if we've already registered. If ($__DotNetSetup_hSection) Then Return SetError(1, 0, 0) ; Size of the memory block we are going to allocate Local $s_nSize = DllStructGetSize(DllStructCreate($tagMMIODATA)) MsgBox(0, "$s_nSize", $s_nSize) ; Allocate mapped memory ; Create a memory-mapping section, set error code = 1000 (WinAPI error) and return if fails $__DotNetSetup_hSection = _WinAPI_CreateFileMapping(0, $s_nSize, $sSectionName) If (Not($__DotNetSetup_hSection)) Then Return SetError(1000, _WinAPI_GetLastError(), False) ; Map the created section into memory address. Set error code = 1000 (WinAPI error) and return if fails $__DotNetSetup_pSection = _WinAPI_MapViewOfFile($__DotNetSetup_hSection) If (Not($__DotNetSetup_pSection)) Then Return SetError(1000, _WinAPI_GetLastError(), False) ; Create an named event $__DotNetSetup_hEventIn = _WinAPI_CreateEvent(0, False, False, $sEventName) ; Set error and return if fails If (Not($__DotNetSetup_hEventIn)) Then Return SetError(1000, _WinAPI_GetLastError(), False) ; Additional event so we can terminate ;$__DotNetSetup_hEventOut = _WinAPI_CreateEvent(0, False, False, $sEventName & '_send') ; This event is only used for terminating, then without it we can still start .Net setup and ; get progress normally, so we do not return error here, instead, flag it and ; then return an success value (true) but with a warning (set @error and @extended flag) Local $iError[2] = [0, 0] If (Not($__DotNetSetup_hEventOut)) Then $iError[0] = 1000 $iError[1] = _WinAPI_GetLastError() EndIf ; Now write the event name into the memory-mapped section Local $tMMIOData = DllStructCreate($tagMMIODATA, $__DotNetSetup_pSection) $struct = DllStructSetData($tMMIOData, 'm_szEventName', $sEventName) If @error Then MsgBox(0, "$struct error", "error: " & @error) Exit Else MsgBox(0, "no $struct error", DllStructGetSize($struct)) EndIf ; Save the section name so we can use it later. ; The event name is already written in the section so we don't need to save it $__DotNetSetup_sSection = $sSectionName ; Since we allocate memory, we must finalize (delocate memory). ; If the .NET setup is successful, it will free the memory for us, ; if not, we must free ourselve or we cannot use that memory regions ; (memory leaks, not so scare since a restart can resolve it, but better safe than sorry). OnAutoItExitRegister('__DotNetSetup_Finalize') Return SetError($iError[0], $iError[1], True) EndFunc Func __DotNetSetup_Cleanup($bFreeMemory = True) If ($bFreeMemory) Then If ($__DotNetSetup_hEventIn) Then _WinAPI_CloseHandle($__DotNetSetup_hEventIn) If ($__DotNetSetup_hEventOut) Then _WinAPI_CloseHandle($__DotNetSetup_hEventOut) If ($__DotNetSetup_pSection) Then _WinAPI_UnmapViewOfFile($__DotNetSetup_pSection) If ($__DotNetSetup_hSection) Then _WinAPI_CloseHandle($__DotNetSetup_hSection) EndIf $__DotNetSetup_hEventIn = 0 $__DotNetSetup_hEventOut = 0 $__DotNetSetup_pSection = 0 $__DotNetSetup_hSection = 0 $__DotNetSetup_sSection = 0 EndFunc Func __DotNetSetup_Finalize() __DotNetSetup_Cleanup(True) EndFunc
  4. Its not working for me but I'm still stepping through it, I got a few syntax errors so I'm making sure fixing those I didn't break anything else. Just wanted to get back to you. Pretty much all that I did to 'fix' the syntax errors were to put the global variables at the top, little things like that. I'll keep trying.
  5. Hey I just saw the response, haven't had time to test anything out but THANK YOU! I really appreciate the time you've given to helping me. I'll run it through, and post back in a day or two...hopefully without too many questions . This kind of programming is definitely over my head, but I really look forward to understanding how it works.
  6. Hey binhnx, can I send you a few good drinks! I am unfortunately still not getting it. I think I get what you are saying...here is how I understand it. Run the .net setup with -pipe "myeventname" use $obj = ObjCreate("myeventname.??") then use ObjEvent($obj, ?? ) I did try to code it and tried a few variations but I'm definitely missing something. Here is the broken code I have so far, not much obviously. My next step is try to learn basic stuff about C, try to understand it that way. ;$pid = Run(@ScriptDir & "\dotNetFx40_Full_x86_x64.exe -pipe TheSectionName", "", @SW_SHOW) Sleep(500) $oNet = ObjCreate("TheSectionName.event") If IsObj($oNet) Then MsgBox(0, "", "is obj") Else MsgBox(0, "", "is NOT obj") EndIf Exit $hGUI = GUICreate(".Net Progress Bar", 615, 250) $Progress = GUICtrlCreateProgress(64, 32, 505, 65) GUICtrlCreateLabel("Installing .Net ", 176, 112, 246, 39) GUICtrlSetFont(-1, 20, 800, 0, "Trebuchet MS") GUICtrlSetColor(-1, 0x000000) $b_quit = GUICtrlCreateButton("Quit", 488, 184, 105, 57) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $b_quit ExitLoop EndSwitch WEnd
  7. Thanks binhnx, I'm sorry I am still so lost. I'm looking at the 4.0 example but can't make much more sense of it. I've attached what I believe is the right C++ code, and the link is here (http://code.msdn.microsoft.com/NET-Framework-4-Chainer-5dc250a1/sourcecode?fileId=45405&pathId=663039622) Do I want to use GUIRegisterMsg with the piped MMIO name? Is that how you are expected to worked with MMIO events? I can't find any examples for this except the msdn one written in C++, was hoping to find something in vbs or something closer to Autoit. #pragma once #include <windows.h> #include "IProgressObserver.h" namespace ChainerSample { // MMIO data structure for inter-process communication struct MmioDataStructure { bool m_downloadFinished; // Is download done yet? bool m_installFinished; // Is installer operation done yet? bool m_downloadAbort; // Set to cause downloader to abort bool m_installAbort; // Set to cause installer operation to abort HRESULT m_hrDownloadFinished; // HRESULT for download HRESULT m_hrInstallFinished; // HRESULT for installer operation HRESULT m_hrInternalError; // Internal error from MSI if applicable WCHAR m_szCurrentItemStep[MAX_PATH]; // This gives the windows installer step being executed if an error occurs // while processing an MSI, for example, "Rollback" unsigned char m_downloadProgressSoFar; // Download progress 0 - 255 (0 to 100% done) unsigned char m_installProgressSoFar; // Install progress 0 - 255 (0 to 100% done) WCHAR m_szEventName[MAX_PATH]; // Event that chainer creates and chainee opens to sync communications. }; // This is the class structure that one needs to follow to implement a chainer. // You would derive your server class from MMIOChainer to chain the .NET 4 Redistributable. // // MmioChainerBase class manages the communication and synchronization data // structures. It also implements common get accessors (for chainer) and set accessors (for chainee). class MmioChainerBase { HANDLE m_section; HANDLE m_event; MmioDataStructure* m_pData; protected: // Constructor MmioChainerBase(HANDLE section, HANDLE hevent) : m_section(section) , m_event(hevent) , m_pData(MapView(section)) { } // Destructor virtual ~MmioChainerBase() { if (m_pData) { ::UnmapViewOfFile(m_pData); } } public: HANDLE GetEventHandle() const { return m_event; } HANDLE GetMmioHandle() const { return m_section; } MmioDataStructure* GetData() { return m_pData; } //This is called by the chainer. void Init(LPCWSTR eventName) { //Don't do anything if it is invalid. if (NULL == m_pData) { return; } // Common items for download and install wcscpy_s(m_pData->m_szEventName, MAX_PATH, eventName); // Download specific data m_pData->m_downloadFinished = false; m_pData->m_downloadProgressSoFar = 0; m_pData->m_hrDownloadFinished = E_PENDING; m_pData->m_downloadAbort = false; // Install specific data m_pData->m_installFinished = false; m_pData->m_installProgressSoFar = 0; m_pData->m_hrInstallFinished = E_PENDING; m_pData->m_installAbort = false; m_pData->m_hrInternalError = S_OK; } // This is called by the chainer to force the chained setup to be canceled. void Abort() { //Don't do anything if it is invalid. if (NULL == m_pData) { return; } // Chainer told us to cancel. m_pData->m_downloadAbort= true; m_pData->m_installAbort = true; } // Called when chainer wants to know if chained setup has finished both download and installation. bool IsDone() const { if (NULL == m_pData) { return true; } return m_pData->m_downloadFinished && m_pData->m_installFinished; } // Called by the chainer to get the overall progress, i.e., the combination of the download and installation. unsigned char GetProgress() const { if (NULL == m_pData) { return 255; } return (m_pData->m_downloadProgressSoFar + m_pData->m_installProgressSoFar)/2; } // Get download progress. unsigned char GetDownloadProgress() const { if (NULL == m_pData) { return 255; } return m_pData->m_downloadProgressSoFar; } // Get the installation progress. unsigned char GetInstallProgress() const { if (NULL == m_pData) { return 255; } return m_pData->m_installProgressSoFar; } // Get the combined setup result, installation taking priority over download if both failed. HRESULT GetResult() const { if (NULL == m_pData) { return S_FALSE; } if (m_pData->m_hrInstallFinished != S_OK) { return m_pData->m_hrInstallFinished; } else { return m_pData->m_hrDownloadFinished; } } // Get the download result. HRESULT GetDownloadResult() const { if (NULL == m_pData) { return S_FALSE; } return m_pData->m_hrDownloadFinished; } // Get the installation result. HRESULT GetInstallResult() const { if (NULL == m_pData) { return S_FALSE; } return m_pData->m_hrInstallFinished; } // Get the internal result. const HRESULT GetInternalResult() const { if (NULL == m_pData) { return S_FALSE; } return m_pData->m_hrInternalError; } // Get the current item step from chainee. const CString GetCurrentItemStep() const { if (NULL == m_pData) { return L""; } return CString(m_pData->m_szCurrentItemStep); } // The chainee calls this to see if the chainer has asked that we cancel. bool IsAborted() const { if (NULL == m_pData) { return false; } return m_pData->m_installAbort || m_pData->m_downloadAbort; } protected: // Protected utility function to map the file into memory. static MmioDataStructure* MapView(HANDLE section) { if (NULL == section) { return reinterpret_cast<MmioDataStructure*>(NULL); } return reinterpret_cast<MmioDataStructure*>(::MapViewOfFile(section, FILE_MAP_WRITE, 0, 0, // offsets sizeof(MmioDataStructure))); } }; // This is the class that the consumer (chainer) should derive from. class MmioChainer : protected MmioChainerBase { public: // Constructor MmioChainer (LPCWSTR sectionName, LPCWSTR eventName) : MmioChainerBase(CreateSection(sectionName), CreateEvent(eventName)) { Init(eventName); } // Destructor virtual ~MmioChainer () { ::CloseHandle(GetEventHandle()); ::CloseHandle(GetMmioHandle()); } public: // The public methods: Abort and Run. using MmioChainerBase::Abort; using MmioChainerBase::GetInstallResult; using MmioChainerBase::GetInstallProgress; using MmioChainerBase::GetDownloadResult; using MmioChainerBase::GetDownloadProgress; using MmioChainerBase::GetCurrentItemStep; HRESULT GetInternalErrorCode() { return GetInternalResult(); } // Called by the chainer to start the chained setup. This blocks until setup is complete. void Run(HANDLE process, IProgressObserver& observer) { HANDLE handles[2] = { process, GetEventHandle() }; while(!IsDone()) { DWORD ret = ::WaitForMultipleObjects(2, handles, FALSE, 100); // INFINITE ?? switch(ret) { case WAIT_OBJECT_0: { // Process handle closed. Maybe it blew up, maybe it's just really fast. Let's find out. if (IsDone() == false) // Not a good sign. { HRESULT hr = GetResult(); if (hr == E_PENDING) // Untouched observer.Finished(E_FAIL); else observer.Finished(hr); return; } break; } case WAIT_OBJECT_0 + 1: observer.OnProgress(GetProgress()); break; default: break; } } observer.Finished(GetResult()); } private: static HANDLE CreateSection(LPCWSTR sectionName) { return ::CreateFileMapping (INVALID_HANDLE_VALUE, NULL, // Security attributes PAGE_READWRITE, 0, // High-order DWORD of maximum size sizeof(MmioDataStructure), // low-order DWORD of maximum size. sectionName); } static HANDLE CreateEvent(LPCWSTR eventName) { return ::CreateEvent(NULL, FALSE, FALSE, eventName); } }; // This class is used by the chainee. class MmioChainee : protected MmioChainerBase { public: MmioChainee(LPCWSTR sectionName) : MmioChainerBase(OpenSection(sectionName), OpenEvent(GetEventName(sectionName))) { } virtual ~MmioChainee() { } private: static HANDLE OpenSection(LPCWSTR sectionName) { return ::OpenFileMapping(FILE_MAP_WRITE, //Read/write access FALSE, // Do not inherit the name. sectionName); } static HANDLE OpenEvent(LPCWSTR eventName) { return ::OpenEvent (EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, eventName); } static CString GetEventName(LPCWSTR sectionName) { CString cs = L""; HANDLE handle = OpenSection(sectionName); if (NULL == handle) { DWORD dw; dw = GetLastError(); printf("OpenFileMapping fails with last error: %08x",dw); } else { const MmioDataStructure* pData = MapView(handle); if (pData) { cs = pData->m_szEventName; ::UnmapViewOfFile(pData); } ::CloseHandle(handle); } return cs; } }; }
  8. Hi all, Wondering if doing something like this in Autoit is possible, and if anyone can help me figure out where to start. The installation of .Net 4.5.1 allows for a 'piping' to a memory mapped segment in order to get the progress of the installation. http://msdn.microsoft.com/en-us/library/ff859983(v=vs.110).aspx This way, you can use a parent installer program but have feedback about the installation progress. They have a sample script in C++ http://code.msdn.microsoft.com/NET-Framework-45-Developer-e416a0ba/sourcecode?fileId=47345&pathId=663039622 , and also on the first link there are code sections. You can download .Net 4.5.1 http://www.microsoft.com/en-us/download/details.aspx?id=40773 (web installer) if you want to try the commands out. Thanks in advance, I'm really not sure where to start.
  9. I'll keep looking into it for you... I know there are a ton of MSI properties but I don't 't think they are all available outside of the MSI installing. You are looking to get TARGETDIR. The knownfolderID is something different entirely. It is for getting folder paths of folders such as my documents. Its the current equivalent to CSIDL. I'll ask someone at work about this Monday who knows more about MSIs. If you don't hear back from me PM me as I'm more forgetful then I would like these days.
  10. This was the best I could come up with... Seems like it just pulls the InstallLocation key in HKLM...Uninstall I'll try to invest more time in it to see if I can come up with how to get the product by GUID, but maybe this will point you on the right track at least. $installer = ObjCreate("WindowsInstaller.Installer") $products = $installer.Products For $product In $products MsgBox(0, "", "ProductName= " & $installer.ProductInfo($product, "ProductName") & " Version= " & $installer.ProductInfo($product, "Version") & @CRLF & "Location= " & $installer.ProductInfo($product, "InstallLocation")) Next
  11. There is something a little funny about your code, but it works for me by removing the stop command and increasing your sleep a little to 250. But I still don't understand why you are doing this, I gave you a non loop and a looping method that work. Non loop #include <IE.au3> $oIE = _IECreate() _IEAction($oIE, "printdefault") $hWnd = WinWait("Save PDF File As") ControlSend($hWnd, "", "Edit1", 'This file name ') Loop $oIE = _IECreate() _IEAction($oIE, "printdefault") Do Sleep(250) $hWnd = WinGetHandle("Save PDF File As") Until Not @error ControlSend($hWnd, "", "Edit1", 'This file name ') I have run it a bunch of times on my Win 7x64 box running IE8.
  12. This also works reliably for me $oIE = _IECreate() _IEAction($oIE, "printdefault") Do Sleep(250) $hWnd = WinGetHandle("Save PDF File As") Until Not @error MsgBox(0, "", $hWnd)
  13. Why are you doing a loop in the first place? WinWait will wait (until timeout) for the window to exist, the loop to grab the handle isn't needed.
  14. Hey I think you are making this a little harder on yourself then you need to..let me know if this works for you #include <IE.au3> $oIE = _IECreate() _IEAction($oIE, "printdefault") WinWait("Save PDF File As") $handle = WinGetHandle("Save PDF File As") MsgBox(0, "", $handle)
×
×
  • Create New...