GTAVLover Posted July 8, 2017 Share Posted July 8, 2017 I use following code to call ShellExecuteEx and it works fine. Local $ShExecInfo = DllStructCreate('STRUCT; DWORD cbSize; ULONG fMask; HWND hwnd; PTR lpVerb; PTR lpFile; PTR lpParameters; PTR lpDirectory; INT nShow; HANDLE hInstApp; PTR lpIDList; PTR lpClass; HANDLE hkeyClass; DWORD dwHotKey; HANDLE hIcon; HANDLE hProcess; ENDSTRUCT') Local $lpVerb = DllStructCreate('WCHAR[15];WCHAR') Local $lpFile = DllStructCreate('WCHAR[255];WCHAR') Local $lpParameters = DllStructCreate('WCHAR[255];WCHAR') Local $lpDirectory = DllStructCreate('WCHAR[255];WCHAR') DllStructSetData($lpVerb, 1, '') DllStructSetData($lpFile, 1, 'C:\Windows\Notepad.exe') DllStructSetData($lpParameters, 1, '') DllStructSetData($lpDirectory, 1, '') DllStructSetData($ShExecInfo, 'cbSize', DllStructGetSize($ShExecInfo)) DllStructSetData($ShExecInfo, 'fMask', BitOR(0xC, 0x40, 0x400)) DllStructSetData($ShExecInfo, 'hwnd', NULL) DllStructSetData($ShExecInfo, 'lpVerb', DllStructGetPtr($lpVerb)) DllStructSetData($ShExecInfo, 'lpFile', DllStructGetPtr($lpFile)) DllStructSetData($ShExecInfo, 'lpParameters',DllStructGetPtr($lpParameters)) DllStructSetData($ShExecInfo, 'lpDirectory', DllStructGetPtr($lpDirectory)) DllStructSetData($ShExecInfo, 'nShow', @SW_SHOW) Local $Result = DllCall('Shell32.dll', 'BOOL', 'ShellExecuteExW', 'PTR', DllStructGetPtr($ShExecInfo))[0] ConsoleWriteError('ShellExecuteEx: ' & String($Result) & ' ' & String(_WinAPI_GetLastErrorMessage()) & @CRLF) Exit 1 But the problem is I can't declare some items in struct such as lpFile, lpDirectory (whose items have String data type) in AutoIt. If I declare they in String type like: Local $ShExecInfo = DllStructCreate('STRUCT; DWORD cbSize; ULONG fMask; HWND hwnd; WSTR lpVerb; WSTR lpFile; WSTR lpParameters; WSTR lpDirectory; INT nShow; HANDLE hInstApp; PTR lpIDList; WSTR lpClass; HANDLE hkeyClass; DWORD dwHotKey; HANDLE hIcon; HANDLE hProcess; ENDSTRUCT') And use it like: DllStructSetData($ShExecInfo, 'lpVerb', '') DllStructSetData($ShExecInfo, 'lpFile', 'C:\Windows\Notepad.exe') DllStructSetData($ShExecInfo, 'lpParameters', '') DllStructSetData($ShExecInfo, 'lpDirectory', '') AutoIt crashes end script doesn't execute. But I can't figure why it works when I declare them as PTR type. Doing so also increase number of code lines, I want to declare they as WSTR anyway to reduce number of code lines. Any help is greatly appreciated to know what goes wrong with WideString type here. Link to comment Share on other sites More sharing options...
RTFC Posted July 8, 2017 Share Posted July 8, 2017 (edited) Welcome to the AutoIt forums. 7 hours ago, GTAVLover said: I want to declare they as WSTR anyway to reduce number of code lines. You can't, that's not how it works. When you use a dynamic link library that you haven't written yourself (such as shell32), you have to play by its rules, just as when you use an AutoIt UDF, you have to parse the (types of) arguments it expects, and in the right order, or else the call will likely fail. In this case, shell32 expects pointers to work buffers to be pushed onto the stack (i.e., 4/8 bytes each), not the buffers themselves (which take up much more space than the pointers to them would, e.g., here some are 255 bytes each). It can then perform operations on the indicated memory regions. It would be incredibly inefficient to parse those buffers themselves back and forth every time (I write dlls that handle buffers that are GBs in size; can you imagine (how long it would take to be) shuffling those around for each call? You don't want to be re-allocating, copying everything across, performing an action there, copying everything back, and de-allocating, when all you really have to do is tell the dll: "you need to do X on some data that live in location Y"). So unless you're willing to write your own dlls that behave the way you want them to, you'll have to conform to their specifications, or else you don't get to play. Edited July 8, 2017 by RTFC GTAVLover 1 My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
GTAVLover Posted July 8, 2017 Author Share Posted July 8, 2017 Okay..... Thanks for reply. But why MSDN listed those parameters as LPCTSTR instead of ptr?? Link to comment Share on other sites More sharing options...
mikell Posted July 8, 2017 Share Posted July 8, 2017 LPCTSTR = Long Pointer to a Const TCHAR STRing Not very clear here where MS says : lpVerb = Type: LPCTSTR "A string, referred to as a verb" BUT lpFile = Type: LPCTSTR "The address of a null-terminated string" Thanks Microsoft GTAVLover 1 Link to comment Share on other sites More sharing options...
GTAVLover Posted July 8, 2017 Author Share Posted July 8, 2017 2 minutes ago, mikell said: LPCTSTR = Long Pointer to a Const TCHAR STRing Not very clear here where MS says : lpVerb = Type: LPCTSTR "A string, referred to as a verb" BUT lpFile = Type: LPCTSTR "The address of a null-terminated string" Thanks Microsoft Ahh okay......That's why it won't work with WideString........Thanks guys ........ And does AutoIt suport Unions in such API functions? I think it isn't. Link to comment Share on other sites More sharing options...
GTAVLover Posted July 8, 2017 Author Share Posted July 8, 2017 But, I can't figure why even there are ShellExecute and many other Windows API functions those require LPCTSTR as parameters, work with normal String type instead Pointers? I tested and worked, can't figure why this happened only with ShellExecuteEx. Link to comment Share on other sites More sharing options...
Danyfirex Posted July 9, 2017 Share Posted July 9, 2017 Hello. The issue is that AutoIt structures does not support wstr LPCSTR,LPSTRSTR LPCWSTR,LPWSTRWSTR as C/C++. For that reason you need to create an structure. If dllstructure allow you wstr and str data types it was correct did the way you tried. using something like this WSTR lpFile (Of couse AutoIt does not support that kind of structure data type) DllStructSetData($ShExecInfo, 'lpFile', 'C:\Windows\Notepad.exe') But as I said if was possible if AutoIt allow you that data type in dll structures but it does not, So it will not work. So for that reason you need to create the strings structures. ;~ If you'll use UNICODE unicode Local $lpVerb = DllStructCreate('WCHAR[15];') Local $lpFile = DllStructCreate('WCHAR[255];') Local $lpParameters = DllStructCreate('WCHAR[255];') Local $lpDirectory = DllStructCreate('WCHAR[255];') ;~ If you'll use ANSI version Local $lpVerb = DllStructCreate('CHAR[15];') Local $lpFile = DllStructCreate('CHAR[255];') Local $lpParameters = DllStructCreate('CHAR[255];') Local $lpDirectory = DllStructCreate('CHAR[255];') ;pd: of course the size could be diferent Sorry for post code without correct tag my connections is unable to load the popup window for put the code. MSDN is clear enough I think when it says: lpFile Type: LPCTSTR The address of a null-terminated string that specifies the name of the file or object on which ShellExecuteEx will perform the action specified by the lpVerb parameter. So what is the address? $MyAddress=DllStructGetPtr($lpFile) the we put it in our HELLEXECUTEINFO structure DllStructSetData($ShExecInfo, 'lpFile',$MyAddress) that's all. Saludos GTAVLover and Skysnake 2 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
GTAVLover Posted July 9, 2017 Author Share Posted July 9, 2017 Then, for other API functions such as ShellExecute, I don't create string structures and just pass strings as parameters (Thay also require LPCTSTR parameters).......But they works fine without those string structures in AutoIt.......Why this? Link to comment Share on other sites More sharing options...
mikell Posted July 9, 2017 Share Posted July 9, 2017 ShellExecute uses literal params (no struct) while ShellExecuteEx uses a pointer to SHELLEXECUTEINFO only You might have even more fun by looking into the "WinAPIShellEx.au3" UDF to the _WinAPI_ShellExecute func and see how AutoIt handles the thingy Dazing: in this func, wstr is used in the call if the parameter value is defined, but if not then ptr is used with the value 0 (implied: pointer to default) Nice GTAVLover 1 Link to comment Share on other sites More sharing options...
Danyfirex Posted July 9, 2017 Share Posted July 9, 2017 12 hours ago, GTAVLover said: Then, for other API functions such as ShellExecute, I don't create string structures and just pass strings as parameters (Thay also require LPCTSTR parameters).......But they works fine without those string structures in AutoIt.......Why this? That happends because AutoIt include the nice parameter type wstr and str that allow you to wrap all structutures stuffs just using wstr,str. why? this simply happeds because AutoIt does no support string Pointer directry as many other programing lenguages. But you here is an example of using structures in common dllcalls. Local $sFilePath="notepad.exe" Local $tFilePath=DllStructCreate("WCHAR Data[" & StringLen($sFilePath) & "]") $tFilePath.Data=$sFilePath Local $pFilePath=DllStructGetPtr($tFilePath,1) ;this is the prefered correct way DllCall('shell32.dll', 'ULONG_PTR', 'ShellExecuteW', 'hwnd', 0, "wstr", Null, 'wstr', $sFilePath, _ "wstr", Null, "wstr", Null, 'int', 10) ;this is also correct (but please use wstr/str instead) ;~ DllCall('shell32.dll', 'ULONG_PTR', 'ShellExecuteW', 'hwnd', 0, "wstr", Null, 'ptr', $pFilePath, _ ;~ "wstr", Null, "wstr", Null, 'int', 10) ;even this can be correct (but please use wstr/str instead) ;~ DllCall('shell32.dll', 'ULONG_PTR', 'ShellExecuteW', 'hwnd', 0, "wstr", Null, 'struct*', $tFilePath, _ ;~ "wstr", Null, "wstr", Null, 'int', 10) 8 hours ago, mikell said: ShellExecute uses literal params (no struct) while ShellExecuteEx uses a pointer to SHELLEXECUTEINFO only You might have even more fun by looking into the "WinAPIShellEx.au3" UDF to the _WinAPI_ShellExecute func and see how AutoIt handles the thingy Dazing: in this func, wstr is used in the call if the parameter value is defined, but if not then ptr is used with the value 0 (implied: pointer to default) Nice You also can used Null without change the parameter type to ptr and pass value 0. "wstr",Null Null was created for that. Saludos GTAVLover 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
GTAVLover Posted July 10, 2017 Author Share Posted July 10, 2017 Thanks all for help....... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now