Set up a TM1 model as a service or an application in AutoHotKey

Introduction

In an earlier article on this website I blogged about running a TM1 model in different ways:

  1. TM1 runs as a service
  2. TM1 runs as an application
  3. TM1 runs as local server

This article focuses on running TM1 both as an application or as a service.

You also read about me using an automation tool called AutoHotKey. In fact, over the years of TM1 consultancy, I have set up so many models as applications that I wanted to automate the steps to do so. This involves:

  1. setting up a tm1s.cfg file, making sure good configuration settings are applied
  2. setting up a database directory
  3. setting up a logging directory
  4. setting up a shortcut to launch the model
  5. adding a couple of other folders that are often used

So 1 and 1 makes 2, I wrote my own AutoHotKey script to help me setting up a TM1 server as an application. In general, you would do so for different reasons, but the main reason is the temporary character:

  1. when I need to answer a query from my consultancy customers, I could fire up an older backup to check and validate
  2. for a smaller POC, you could suffice with an application
  3. to retrieve data from a cube that is located in a different folder (for instance a backup) a temporary model will suffice
  4. etc.

Usually though you would set up a TM1 model as a service. The most important reason is that services, unlike applications, are not as likely to be turned off. When a user logs off his application will be stopped too and so does the TM1 model.

I posted my code on the TM1 forum (in the Useful code, tips and tricks section). Once you set up the tool (at least some knowledge of AHK is needed but not very much), please go to Windows Explorer and start the tool. I assign the shortcut Alt + F12 but you choose what you like best.

The first action of the tool is to navigate to the folder containing the tm1s.cfg file. The script contains a number of options, for example create a tm1s.cfg file if it does not exist, select the data directory by clicking the folder name, assigning random port numbers, create custom folders, etc. Communication with the user is organized via Inputboxes, Msgboxes and file explorers to select a folder.

To sum up, the rationale behind this script is saving time and effort because of typo's, repetitive actions, looking up folder names and so on, copying existing files and folders, ... after setting up a few 100s of these I got pretty tired :lol: You only need this code and no other libraries.

Enjoy !

#SingleInstance force

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Alt-F12 | Create a shortcut to run a TM1 model as an application
;
; Wim Gielis
; http://www.wimgielis.com
; October 2019
;
; Remarks:
; - output is a shortcut or a service to run a TM1 model
; - with a userform to guide the user
; - the tm1s.cfg file can be created/updated
; - the config file for TM1 is not necessarily part of the TM1 data directory
; - there is only 1 folder for the TM1 data directory
; - the TM1 logging directory is part of the TM1 data directory, and is called "Logs", unless you choose the logging directory yourself
; - TM1 server name can be set too. Do this before launching this tool. A number of other settings are set in this script, though, for your convenience
; - you can also delete all commentary lines (lines starting with #). For instance, IBM's cfg file is quite big and not needed for simple models
; - and a lot more !
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; initializations for starting a local TM1 model
ReadIn_TM1_server_location_Settings:

    ; initializations for Windows

    ; IniRead, cWin_Username, %INI_Settings_File%, Win_Settings, Win_username, %c00%
    ; IniRead, cWin_Password, %INI_Settings_File%, Win_Settings, Win_password, %c00%
    cWin_Username := ...\...
	cWin_Password := ...

    ; IniRead, cPath_TM1s_exe, %INI_Settings_File%, TM1, Path_TM1s_exe, %c00%
    ; cPath_TM1s_exe := ReplaceEnvVars(cPath_TM1s_exe)
	; IfNotExist, %cPath_TM1s_exe%
       cPath_TM1s_exe := "C:\Program Files\ibm\cognos\tm1_64\bin64\tm1s.exe"

    SplitPath, cPath_TM1s_exe, , dir
    cPath_TM1sd_exe := % dir . "\tm1sd.exe"
    Return

	
!F12:: ; <-- (Windows Explorer) Create a shortcut or service to run a TM1 model
{
GoSub, ReadIn_TM1_server_location_Settings
currentpath :=
{
    v =
    v := GetSelectedFileFolderNames_UnderCursor()
	if v
	   currentpath = %v%
	else
	{
        v := GetSelectedFileFolderNames_FolderYouSee()
	    if v
	       currentpath = %v%
	    else
	       return
	}
}
currentpath := StrSplit(currentpath, "`n" )[1]

if InStr( FileExist(currentpath), "D") == 0
    {
	; take the folder
    SplitPath, currentpath, , currentpath
	}

gui, destroy
gui, tm1_as_app:new

gui, add, Button, vBut1 gBut x10 y+20 w150, Select folder of TM1s.cfg
gui, add, edit, vEdi1 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx1 x+20

gui, add, Button, vBut2 gBut x10 w150, Select data dir
gui, add, edit, vEdi2 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx2 x+20

gui, add, Button, vBut3 gBut x10 w150, Select logging dir
gui, add, edit, vEdi3 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx3 x+20

gui, add, Button, vBut4 gBut x10 w150, TM1 server exe
gui, add, edit, vEdi4 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx4 x+20

gui, add, Button, vBut6 gBut x10 w150, Select folder of shortcut
gui, add, edit, vEdi6 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx6 x+20

gui, add, Text, x10 w150, Shortcut / service name
gui, add, edit, vEdi5 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx5 x+20

gui, add, Text, x10 w150, Specify the TM1 model name
gui, add, edit, vEdi7 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx7 x+20

gui, add, Text, x10 w150, Username for the service
gui, add, edit, vEdi8 x+20 w500 r1 gChanged_Editbox
gui, add, CheckBox, vChbx8 x+20

gui, add, Text, x10 w150, Password for the username
gui, add, edit, vEdi9 x+20 w500 r1 gChanged_Editbox Password
gui, add, CheckBox, vChbx9 x+20

Gui, add, ListBox, r2 x250 choose1 gChanged_AppOrService vAppOrService, Create a shortcut|Create a service
Gui, add, CheckBox, Checked0 vChbx_RunModel x10 y+20, Run the TM1 model ?
Gui, add, CheckBox, Checked vChbx_Put_In_Default_Values, Put in default values ?
Gui, add, CheckBox, Checked0 x10 vChbx_Create_Addit_Folders, Create additional folders ?
Gui, add, CheckBox, Checked vChbx_Remove_Unnecessary_Lines, Remove unnecessary lines that are commented out ?
Gui, add, ListBox, r2 choose1 vAdminHostChoice, Localhost|%A_computername%
Gui, add, ListBox, r4 choose4 vChoresChoice, Delete chores|Deactivate chores|Activate chores|Leave untouched

GuiControl,,Edi1, %currentpath%
GuiControl,,Edi4, %cPath_TM1s_exe%

GuiControl,,Edi8, %cWin_Username%
GuiControl, Disable, Edi8
GuiControl, Disable, Chbx8
GuiControl,,Edi9, %cWin_Password%
GuiControl, Disable, Edi9
GuiControl, Disable, Chbx9

gui, add, Button, vBut7 gBut w100, Exit
gui, add, Button, vBut8 gBut x+150 w200 Default, Create

gui, show, , Run a TM1 model

return

But:
  gui, Submit, NoHide
  If (a_guicontrol = "But1") {
	FileSelectFolder, fld, *%Edi1%, 3, Select the folder containing the tm1s.cfg file`n(if missing it can be generated)
	If ErrorLevel
       {
       GuiControl,,Edi1,
	   }
    Else
	   {
	   fld := RegExReplace(fld, "\\$")
       GuiControl,,Edi1, % fld
	   }

  }
  If (a_guicontrol = "But2") {
    If( %Edi2% <> "" )
       FileSelectFolder, fld, *%Edi2%
    Else
       FileSelectFolder, fld, *%Edi1%
    If ErrorLevel
       {
       GuiControl,,Edi2,
	   }
    Else
	   {
	   fld := RegExReplace(fld, "\\$")
       GuiControl,,Edi2, % fld
	   }
  }
  If (a_guicontrol = "But3") {
    If( %Edi3% <> "" )
       FileSelectFolder, fld, *%Edi3%
    Else
       FileSelectFolder, fld, *%Edi1%
    If ErrorLevel
       {
       GuiControl,,Edi3,
	   }
    Else
	   {
	   fld := RegExReplace(fld, "\\$")
       GuiControl,,Edi3, % fld
	   }
  }
  If (a_guicontrol = "But4") {
	FileSelectFile, fil, 3, %cPath_TM1s_exe%, Select the TM1s.exe file (*.exe)
    If ErrorLevel
       {
       GuiControl,,Edi4,
	   }
    Else
	   {
       GuiControl,,Edi4, % fil
	   }
  }
  If (a_guicontrol = "But6") {
	FileSelectFolder, fld, *%Edi1%, 3, Select the folder that will contain the shortcut
	If ErrorLevel
       {
       GuiControl,,Edi6,
	   }
    Else
	   {
	   fld := RegExReplace(fld, "\\$")
       GuiControl,,Edi6, % fld
	   }

  }
  If (a_guicontrol = "But7") {
    gui, destroy
  }
  If (a_guicontrol = "But8") {





    c01 = %Edi1%\tm1s.cfg

    ; treating the TM1 data directory
    vExisting_Cfg := FileExist(c01)
    IniWrite, %Edi7%, %c01%, TM1S, ServerName

    DataDirFolder := Edi2
    Folder_Data_Dir = %DataDirFolder%
    IniWrite, %Folder_Data_Dir%  , %c01%, TM1S, DataBaseDirectory

    LoggingDirFolder := Edi3
    Folder_Log_Dir = %LoggingDirFolder%
	If FileExist( Folder_Log_Dir )
       IniWrite, %Folder_Log_Dir%   , %c01%, TM1S, LoggingDirectory
	Else
	   {
          Folder_Log_Dir = %Folder_Data_Dir%\Logs
	      FileCreateDir, %Folder_Log_Dir%
          IniWrite, %Folder_Log_Dir%   , %c01%, TM1S, LoggingDirectory	   
	   }
	
	IniWrite, %AdminHostChoice%  , %c01%, TM1S, AdminHost

    ; add/update other much used settings in the TM1 data directory
    If Chbx_Put_In_Default_Values = 1
    {
    IniWrite, 1                  , %c01%, TM1S, IntegratedSecurityMode
    IniWrite, F                  , %c01%, TM1S, UseSSL
    IniWrite, T                  , %c01%, TM1S, EnableTIDebugging
    IniWrite, T                  , %c01%, TM1S, PersistentFeeders
    IniWrite, T                  , %c01%, TM1S, EnableNewHierarchyCreation

    Random, OutputVar, 8005, 8100
    IniWrite, %OutputVar%        , %c01%, TM1S, HttpPortNumber

    Random, OutputVar, 5000, 49151
    IniWrite, %OutputVar%        , %c01%, TM1S, PortNumber

    IniWrite, T                  , %c01%, TM1S, ParallelInteraction
    IniWrite, T                  , %c01%, TM1S, EnableTIDebugging
    IniWrite, T                  , %c01%, TM1S, ForceReevaluationOfFeedersForFedCellsOnDataChange
    IniWrite, all                , %c01%, TM1S, MTQ

    EnvGet, ProcessorCount, number_of_processors
    ProcessorCount--
    IniWrite, %ProcessorCount%   , %c01%, TM1S, MaximumCubeLoadThreads

    IniWrite, F                  , %c01%, TM1S, TopLogging
    IniWrite, 2                  , %c01%, TM1S, TopScanFrequency
    IniWrite, T                  , %c01%, TM1S, TopScanMode.Threads

    IniWrite, F                  , %c01%, TM1S, MTFeeders
    IniWrite, Kerberos           , %c01%, TM1S, SecurityPackageName
    IniWrite, ENG                , %c01%, TM1S, Language
    IniWrite, T                  , %c01%, TM1S, MTQQuery
    IniWrite, 5000               , %c01%, TM1S, MaximumViewSize
    IniWrite, T                  , %c01%, TM1S, VersionedListControlDimensions
    IniWrite, T                  , %c01%, TM1S, LoadPrivateSubsetsOnStartup
    IniWrite, T                  , %c01%, TM1S, ReduceCubeLockingOnDimensionUpdate
    IniWrite, T                  , %c01%, TM1S, EventLogging
    IniWrite, 1                  , %c01%, TM1S, EventScanFrequency
    IniWrite, 0                  , %c01%, TM1S, EventThreshold.PooledMemoryInMB
    IniWrite, 5                  , %c01%, TM1S, EventThreshold.ThreadBlockingNumber
    IniWrite, 600                , %c01%, TM1S, EventThreshold.ThreadRunningTime
    IniWrite, 20                 , %c01%, TM1S, EventThreshold.ThreadWaitingTime
    IniWrite, T                  , %c01%, TM1S, PullInvalidationSubsets
    IniWrite, F                  , %c01%, TM1S, PerformanceMonitorOn
    IniWrite, F                  , %c01%, TM1S, AuditLogOn
    IniWrite, 1800s              , %c01%, TM1S, AuditLogUpdateInterval
    IniWrite, 2 GB               , %c01%, TM1S, AuditLogMaxFileSize
    IniWrite, 1 GB               , %c01%, TM1S, AuditLogMaxQueryMemory
    IniWrite, 10                 , %c01%, TM1S, ClientPropertiesSyncInterval

    IniRead, LoggingDirectory    , %c01%, TM1S, LoggingDirectory,
    FileCreateDir, %LoggingDirectory%\FileRetry
    IniWrite, %LoggingDirectory%\FileRetry , %c01%, TM1S, FileRetry.FileSpec
    IniWrite, 5                  , %c01%, TM1S, FileRetry.Count
    IniWrite, 2000               , %c01%, TM1S, FileRetry.Delay

    IniRead, LoggingDirectory    , %c01%, TM1S, LoggingDirectory,
    FileCreateDir, %LoggingDirectory%\RawStore
    IniWrite, %LoggingDirectory%\RawStore , %c01%, TM1S, RawStoreDirectory
    FileCreateDir, %LoggingDirectory%\DistribPlanningOutputDir
    IniWrite, %LoggingDirectory%\DistribPlanningOutputDir , %c01%, TM1S, DistributedPlanningOutputDir

    IniDelete                    , %c01%, TM1S, IPAddressV4
    IniDelete                    , %c01%, TM1S, ServerCAMURI
    IniDelete                    , %c01%, TM1S, ClientCAMURI
    IniDelete                    , %c01%, TM1S, ClientPingCAMPassport

	}

	; create additional folders
    If Chbx_Create_Addit_Folders = 1
        {
	    FileCreateDir, %Edi6%\Install files
	    FileCreateDir, %Edi6%\Project files\Control files
	    FileCreateDir, %Edi6%\Project files\Documentation
	    FileCreateDir, %Edi6%\Project files\Input\Data
	    FileCreateDir, %Edi6%\Project files\Input\Metadata
	    FileCreateDir, %Edi6%\Project files\Output
	    FileCreateDir, %Edi6%\Project files\Progress
	    FileCreateDir, %Edi6%\Project files\Templates
	    FileCreateDir, %Edi6%\Project files\Testing
	    FileCreateDir, %Edi6%\Scripts
	    FileCreateDir, %Edi6%\TM1Backup
	    }

	; delete unnecessary lines, only for already existing tm1s.cfg files
    If Chbx_Remove_Unnecessary_Lines = 1
        {
        If vExisting_Cfg
           {
           all =
           Loop, Read, %c01%
           {
           If A_LoopReadLine=
               Continue
	           StringLeft, tmp, A_LoopReadLine, 1
               If( tmp != "#" ) ;If this line isn't starting with # character
                   all = %all%`r`n%A_LoopReadLine%
           }
           StringTrimLeft, all, all, 2 ;Removes first `r`n line
           FileDelete, %c01%
           FileAppend, %all%, %c01%
           }
        }

    ; chores logic
	If ChoresChoice = "Delete chores"
	   {
       IniDelete                    , %c01%, TM1S, StartupChores
	   FileDelete, %Folder_Data_Dir%\*.cho
	   }
    Else If ChoresChoice = Deactivate chores
	   {
           IniDelete                    , %c01%, TM1S, StartupChores
           Loop Files, %Folder_Data_Dir%\*.cho
           {
		   FileRead, OutputVar, %A_LoopFileFullPath%
           SearchTerm := "537,1"
		   If InStr(OutputVar, SearchTerm )
           {
           all =
           Loop, Read, %A_LoopFileFullPath%
           {
		   If A_LoopReadLine=
               Continue
	           StringLeft, tmp, A_LoopReadLine, 5
               If tmp = 537,1
				  all = %all%`r`n537,0
               Else
                  all = %all%`r`n%A_LoopReadLine%
           }
           StringTrimLeft, all, all, 2
           FileDelete, %A_LoopFileFullPath%
           FileAppend, %all%, %A_LoopFileFullPath%
           }
           }
       }
    Else If ChoresChoice = Activate chores
	   {
           Loop Files, %Folder_Data_Dir%\*.cho
           {
		   FileRead, OutputVar, %A_LoopFileFullPath%
           SearchTerm := "537,0"
		   If InStr(OutputVar, SearchTerm )
           {
           all =
           Loop, Read, %A_LoopFileFullPath%
           {
		   If A_LoopReadLine=
               Continue
	           StringLeft, tmp, A_LoopReadLine, 5
               If tmp = 537,0
				  all = %all%`r`n537,1
               Else
                  all = %all%`r`n%A_LoopReadLine%
           }
           StringTrimLeft, all, all, 2
           FileDelete, %A_LoopFileFullPath%
           FileAppend, %all%, %A_LoopFileFullPath%
           }
           }
       }
	
    If AppOrService = Create a shortcut
       {
	   ; the shortcut to launch the model
       FileCreateShortcut, %cPath_TM1s_exe%, %Edi6%\%Edi5%.lnk, , -z"%Edi1%"
	   ; run the shortcut / TM1 model
       If Chbx_RunModel = 1
          Run, %Edi6%\%Edi5%.lnk
	   }
	Else If AppOrService = Create a service
       {
       ; full_command_line := GetParentDir( cPath_TM1s_exe, 1 )
       ; full_command_line := full_command_line . "\tm1sd.exe -install"
       full_command_line := cPath_TM1sd_exe
       full_command_line := full_command_line . " -n""" . Edi5 . """"
       full_command_line := full_command_line . " -z""" . GetParentDir( c01, 1) . """"
       full_command_line := full_command_line . " -u" . Edi8
       full_command_line := full_command_line . " -w" . Edi9

	   If (A_IsAdmin)
          RunWait %full_command_line%,, Hide
       Else
          RunWait *RunAs %full_command_line%,, Hide
       if (ErrorLevel = "ERROR")
          MsgBox An error was produced when creating the service to run the TM1 model. Please investigate.

       full_command_line := "sc config"
       full_command_line := full_command_line . " """ . Edi5 . """"
       full_command_line := full_command_line . " start=auto"
	   If (A_IsAdmin)
	      RunWait %full_command_line%,, Hide

	   ; run the shortcut / TM1 model
       If Chbx_RunModel = 1
          RunWait, cmd /c net start "%Edi5%",, Hide
	   }

    Return
  }

Changed_AppOrService:
  gui, Submit, NoHide
  If AppOrService = Create a shortcut
     {
	 GuiControl, Enable, But6
	 GuiControl, Enable, Edi6
	 GuiControl, Enable, Chbx6

	 GuiControl, Disable, Edi8
	 GuiControl, Disable, Chbx8

	 GuiControl, Disable, Edi9
	 GuiControl, Disable, Chbx9

	 GuiControl,,Edi4, %cPath_TM1s_exe%
	 }
  Else If AppOrService = Create a service
     {
	 GuiControl, Disable, But6
	 GuiControl, Disable, Edi6
	 GuiControl, Disable, Chbx6

	 GuiControl, Enable, But8
	 GuiControl, Enable, Edi8
	 GuiControl, Enable, Chbx8

	 GuiControl, Enable, But9
	 GuiControl, Enable, Edi9
	 GuiControl, Enable, Chbx9
	 
	 GuiControl,,Edi4, %cPath_TM1sd_exe%
	 }
  return


Changed_Editbox:
  gui, Submit, NoHide
  If (a_guicontrol = "Edi1") {

     IfExist, %Edi1%
	    GuiControl, , Chbx1, 1
     Else
	    GuiControl, , Chbx1, 0

     c01 = %Edi1%\tm1s.cfg
     IfExist, %c01%
	    {
		; retrieve the data dir and logging
		IniRead, DataDirFolder,    %c01%, TM1S, DataBaseDirectory,
        If ( InStr( DataDirFolder, ".", false ) > 0 ) OR ( InStr( DataDirFolder, "..", false ) > 0 )
        {
            base = %Edi1%
            rel = %DataDirFolder%
            DataDirFolder := % PathCombine(base, rel)
		}
        IfExist, %DataDirFolder%
            {
			GuiControl, , Chbx2, 1
            GuiControl, , Edi2, %DataDirFolder%
			}
        Else
            {
			GuiControl, , Chbx2, 0
			}

        IniRead, LoggingDirFolder,    %c01%, TM1S, LoggingDirectory,
        If ( InStr( LoggingDirFolder, ".", false ) > 0 ) OR ( InStr( LoggingDirFolder, "..", false ) > 0 )
        {
            base = %Edi1%
            rel = %LoggingDirFolder%
            LoggingDirFolder := % PathCombine(base, rel)
		}
        IfExist, %LoggingDirFolder%
            {
			GuiControl, , Chbx3, 1
			GuiControl, , Edi3, %LoggingDirFolder%
			}
        Else
            GuiControl, , Chbx3, 0

		x = %Edi1%
        StringGetPos, p1, x, \ , R1
        Stringtrimleft, vCustomer, x, (p1+1)
        GuiControl, , Edi5, %vCustomer%

        ; for the path of the shortcut, take the parent folder
		p := GetParentDir(x, 1)
        GuiControl, , Edi6, %p%

        IniRead, TM1ServerName       , %c01%, TM1S, ServerName, E
        GuiControl, , Edi7, %TM1ServerName%
	    }
     Else
     {
		GuiControl, , Edi2,
		GuiControl, , Edi3,
		GuiControl, , Edi7,
     }
  }
  If (a_guicontrol = "Edi2") {
     IfExist, %Edi2%
	    GuiControl, , Chbx2, 1
     Else
	    GuiControl, , Chbx2, 0
  }
  If (a_guicontrol = "Edi3") {
     IfExist, %Edi3%
	    GuiControl, , Chbx3, 1
     Else
	    GuiControl, , Chbx3, 0
  }
  If (a_guicontrol = "Edi4") {
     IfExist, %Edi4%
	    GuiControl, , Chbx4, 1
     Else
	    GuiControl, , Chbx4, 0
  }
  If (a_guicontrol = "Edi5") {
     If( Trim(Edi5) <> "" )
         {
         IfNotExist, %Edi6%\%Edi5%.lnk
	        GuiControl, , Chbx5, 1
         Else
	        GuiControl, , Chbx5, 0
		}
     Else
	    GuiControl, , Chbx5, 0
  }
  If (a_guicontrol = "Edi6") {
     IfExist, %Edi6%
	    GuiControl, , Chbx6, 1
     Else
	    GuiControl, , Chbx6, 0
  }
  If (a_guicontrol = "Edi7") {
     If( Trim(Edi6) <> "" )
	    GuiControl, , Chbx7, 1
     Else
	    GuiControl, , Chbx7, 0
  }
  If (a_guicontrol = "Edi8") {
     If( Trim(Edi8) <> "" )
	    GuiControl, , Chbx8, 1
     Else
	    GuiControl, , Chbx8, 0
  }
  If (a_guicontrol = "Edi9") {
     If( Trim(Edi9) <> "" )
	    GuiControl, , Chbx9, 1
     Else
	    GuiControl, , Chbx9, 0
  }

return
}

tm1_as_appGuiEscape:
  gui, destroy
  ; ExitApp
return

PathCombine(abs, rel) {
    VarSetCapacity(dest, (A_IsUnicode ? 2 : 1) * 260, 1) ; MAX_PATH
    DllCall("Shlwapi.dll\PathCombine", "UInt", &dest, "UInt", &abs, "UInt", &rel)
    Return, dest
}

GetParentDir(Path,Count=1,Delimiter="\") {
  While (InStr(Path,Delimiter) <> 0 && Count <> A_Index - 1)
    Path := SubStr(Path,1,InStr(Path,Delimiter,0,0) - 1)
  Return Path
}

GetSelectedFileFolderNames_UnderCursor()
{
	ToReturn =
	hwnd := hwnd ? hwnd : WinExist("A")
	WinGetClass class, ahk_id %hwnd%
	if (class="CabinetWClass" or class="ExploreWClass" or class="Progman")
		for window in ComObjCreate("Shell.Application").Windows
			if (window.hwnd==hwnd)
               sel := window.Document.SelectedItems
	           for item in sel
	           {
               v := % item.path
			   ToReturn .= v "`n"
               }
    ToReturn := Trim(ToReturn,"`n")
	return ToReturn
}

GetSelectedFileFolderNames_FolderYouSee()
{
    ToReturn =
    WinGetClass, class, A
    if (class="CabinetWClass" or class="ExploreWClass" or class="Progman" or class="WorkerW")
    {
        ControlGetText, currentpath, ToolbarWindow323, ahk_class %class%
        StringTrimLeft, currentpath, currentpath, 9
        if( SubStr( currentpath, 0, 1) == "\")
           currentpath := SubStr(currentpath, 1, StrLen( currentpath ) - 1 )
        ToReturn .= currentpath "`n"
        ToReturn := Trim(ToReturn,"`n")
        Return ToReturn
    }
    Return
}



Homepage

Section contents

About Wim

Wim Gielis is a Business Intelligence consultant and Excel expert

Other links