我在名为main.tcl
的文件夹中有一个名为App
的tcl脚本。脚本中的一行使用来自twapi module的命令(该行实际上在proc中,当用户通过'X'窗口按钮关闭应用程序时,我正在尝试将应用程序最小化到系统托盘):
package require twapi
# ... code here
set hand [twapi::load_icon_from_file tclkit.ico]
# ... code here
文件tclkit.ico
与脚本位于同一目录中(即文件夹App
)。
当main.tcl
运行wish
时,脚本可以正常运行,但在通过命令行将其包装到可执行文件中后,
> tclkit sdx.kit wrap App -runtime tclsh863.exe
可执行文件引发错误,特别是无法找到图标文件:
The system cannot find the file specified.
The system cannot find the file specified.
while executing
"LoadImage $hmod $path $type $opts(width) $opts(height) $flags"
(procedure "twapi::_load_image" line 18)
invoked from within
"twapi::load_icon_from_file tclkit.ico"
(procedure "min_to_tray" line 2)
invoked from within
"min_to_tray"
(command for "WM_DELETE_WINDOW" window manager protocol)
目前的解决方法是将tclkit.ico
文件的副本放在与.exe相同的目录中,但我希望尽可能避免这种情况,并且只有独立的.exe文件。我尝试使用完整路径:
set hand [twapi::load_icon_from_file [file join [pwd] App.exe tclkit.ico]]
通常在我想读取.exe中的文件(.txt,.png文件等)时有效,但没有成功。
所以基本上,有没有办法让.exe从内部加载.ico文件或其他解决方法,不需要依赖.exe应用程序之外的文件?
答案 0 :(得分:1)
核心问题是相关的Windows API实际上采用了文件名,而不是更容易包装从存档中加载(例如缓冲区)。这意味着您必须将文件从存档中复制出来,然后将该名称传递给系统调用。这实际上是Tcl在{{1}}内部执行的操作,当它从不直接向操作系统可见的源中提取DLL时;但它并没有自动为TWAPI做到这一点,因为该库采取的哲学立场只是一个薄的包装并让调用者处理后果(这意味着你可以轻松地做更多的技巧,只要你这样做了本发明)。
我建议将文件复制到某处的临时文件(即这些东西的标准位置; Tcl 8.6 has file tempfile
以帮助处理这种技巧),然后将完整的文件名传递给TWAPI调用。我认为在Windows API中你可以传递一个简单的文件名,你也可以传递一个完整的文件名。 (这实际上很方便......)