thank you for your library.
I did not find a problem, I found an idea, and so I have designed a function that solves the registration of WinSCPnet.dll via Autohotkey and the Windows scripting shell.
A simple user prompt is integrated in the function, which outputs everything necessary for the registration process and asks the user for confirmation. The function can also be executed silently, e.g. because the registration of the assembly must be cancelled after use.
There is no parameter to switch on the silent mode. It is automatically recognised if the user dialogue is not to be displayed (user_dialog := false) and the path to WinSCPnet.DLL is correct.
The function was designed for external calls. But it could also be placed as a method in your library.
I could not test all individualities so far. Therefore, there may well be some programme errors.
; to test the registration of WinSCP, remove the commenting of the next line
;~ result := RegisterWinSCP()
RegisterWinSCP(dllpath:="", user_dialog:=true, unregister:=false) { ; WinSCPnet.dll COM registration/unregistration helper
/* This can be used to register or deregister WinSCP with .NET.
The function can be called in two modes.
The first mode with simple user guidance.
The second is a silent mode, if registration and deregistration are to be carried out without prompting.
The modes are recognised by the parameter values passed (dllpath, user_dialog or unregister).
The user mode has two dialogs. Each dialogue is displayed separately to enable individual dialogue design.
Unless the dialogue display is suppressed with the parameter value of unregister.
*/
__ := Chr(0x22)
batch =
(LTRIM
echo register WinSCPnet.dll 32bit
`%WINDIR`%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe #WinSCPnet.dll# /codebase /verbose ## /tlb
echo.
echo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
echo register WinSCPnet.dll 64bit
`%WINDIR`%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe #WinSCPnet.dll# /codebase /verbose ## /tlb
echo.
echo.
)
; needed to save the state of the action
SetRegView, % (A_PtrSize=8 ? 64 : 32)
RegRead, isRestarted, % "HKEY_CURRENT_USER\SOFTWARE\" A_ScriptName, runAsAdmin
; prerecogniton of silentmode
silentmode := (unregister || (!user_dialog && FileExist(dllpath)))
&& (A_IsAdmin || full_command_line~=" /restart(?!\S)") ? true : false
; script must be executed in administrator mode
full_command_line := DllCall("GetCommandLine", "str")
if !(A_IsAdmin || RegExMatch(full_command_line, " /restart(?!\S)")) {
runasAdmin := "`n! ! Run as administrator ! !`n"
. "Administrator privileges are`nrequired to register the assembly. `n`n"
; return if silentmode is enabled
If silentmode
return -1
}
; check the WinSCP registration
try winscp := ComObjCreate("WinSCP.Session")
catch {
; User dialogs
If !silentmode {
; user dialog
If !isRestarted && (user_dialog||!FileExist(dllpath)||!A_IsAdmin||full_command_line~=" /restart(?!\S)") {
MsgBox, 0x1024, % RegExReplace(A_ScriptName, "\.ah.*$")
, % "--------------------------------------`n"
. " WinSCP Class`n"
. "--------------------------------------`n"
. "`n"
. "The WinSCP.DLL file has to be`n"
. "registered for use with COM.`n"
. runasAdmin
. "Perform the registration now?"
IfMsgBox, No
ExitApp
}
; run as Admin
If runasAdmin {
RegWrite REG_SZ, % "HKEY_CURRENT_USER\SOFTWARE\" A_ScriptName, runAsAdmin, It must! It must!
try {
Run % A_IsCompiled ? ("*RunAs " . __ . A_ScriptFullPath . __ . " /restart")
: ("*RunAs " . __ . A_AhkPath . __ . " /restart " . __ . A_ScriptFullPath . __)
}
ExitApp
}
; deletes registry key, if available
else {
If isRestarted
RegDelete % "HKEY_CURRENT_USER\SOFTWARE\" A_ScriptName, runAsAdmin
}
; get the file path
If !FileExist(dllpath) {
FileSelectFile, ffp, 1, % A_ScriptDir "\..\dll", % "Path to WinSCPnet.dll", WinSCPnet.dll
If (!ffp || !FileExist(ffp)) {
MsgBox, 0x1024, % RegExReplace(A_ScriptName, "\.ah.*$")
, % "----------------------------------------------------------------n"
. " WinSCP Class`n"
. "---------------------------------------------------------------`n"
. "`n"
. "You have not selected a valid path to WinSCPnet.dll.`n"
. "Do you want to cancel the COM registration?"
IfMsgBox, Yes
ExitApp
RegisterWinSCP(dllpath, user_dialog, unregister)
}
dllpath := ffp
}
}
; close winscp Connection
If isObject(winscp)
winscp.CloseConnection()
; for the registration process
batch := StrReplace(batch, "##", "")
batch := StrReplace(batch, "#WinSCPnet.dll#", __ dllpath __)
}
; for the unregistration process
If unregister {
batch := StrReplace(batch, "##", "/unregister")
batch := StrReplace(batch, "#", "")
}
; a console gui
If !silentmode {
Gui, +hwndhOut
Gui, Color, 0x0, 0x0
Gui, Margin, 0, 0
Gui, Font, s10 q5 bold, Consolas
Gui, Add, Edit, xm ym w800 h350 c00D500 hwndhEdit
WinSet, Style , 0x500110C4, % "ahk_id " hEdit
WinSet, ExStyle , 0x00000000, % "ahk_id " hEdit
Gui, Show,, Console output
EditAppend(hEdit, cmdline)
}
; execute batch line by line
shell := ComObjCreate("WScript.Shell")
For each, line in StrSplit(batch, "`n", "`r") {
exec := shell.Exec(ComSpec " /C " line)
txt := exec.StdOut.ReadAll()
out .= txt
!silentmode ? EditAppend(hEdit, txt) : ""
sleep 100
}
; check WinSCP registration
try winscp := ComObjCreate("WinSCP.Session")
catch {
failure := true
; get error message for returning
If !silentmode {
EditAppend(hEdit, "The registration process was successful.")
SetTimer, MoveConsole, -50
MsgBox, 0x1030, % RegExReplace(A_ScriptName, "\.ah.*$")
, % "--------------------------------------------`n"
. " WinSCP Class`n"
. "--------------------------------------------`n"
. "`n"
. "The registration of WinSCPnet.dll`n"
. "was not successful. The error output`n"
. " can be found in the console."
}
}
clipboard := batch . out
; Registration was successful - show it!
If !failure && !silentmode {
EditAppend(hEdit, "The registration process was not successful.")
sleep 15000
}
; close all
shell := ""
DllCall("FreeConsole")
Process, Close, %cPid%
Gui, Destroy
return failure ? 0 : 1
MoveConsole:
hMB := WinExist(RegExReplace(A_ScriptName, "\.ah.*$") " ahk_class #32770")
WinGetPos, mx, my, mw, mh , % "ahk_id " hMB
WinGetPos, wx, wy, ww, wh , % "ahk_id " hOut
WinMove, % "ahk_id " hOut ,, % wx-ww//2
WinMove, % "ahk_id " hMB ,, % mx+mw//2
return
}
EditAppend(hEdit, txt) {
L := DllCall("SendMessage", "Ptr",hEdit, "UInt",0x0E, "Ptr",0 , "Ptr",0) ; WM_GETTEXTLENGTH
DllCall("SendMessage", "Ptr",hEdit, "UInt",0xB1, "Ptr",L , "Ptr",L) ; EM_SETSEL
DllCall("SendMessage", "Ptr",hEdit, "UInt",0xC2, "Ptr",0, "Str",txt ) ; EM_REPLACESEL
}