※ 本文轉寄自 ptt.cc, 文章原始頁面
看板Windows
標題

[問題] 安裝 Console 應用程式

留言62則留言,5人參與討論
推噓13 ( 13049 )
準確來說是把程式目錄新增至環境變數 PATH 之中, 方便在終端機中使用檔名或 basename 呼叫程式並執行。 但當程式越來越多後 PATH 就會變得越來越臃腫。 為了保持 PATH 簡潔,需要統一使用同一個目錄,我嘗試了以下方法。 方法 1. 在同一目錄下放置所有程式的子目錄、檔案 這是最簡單粗暴的方法 但,由於所有程式的子目錄與檔案都混在一起, 可能遇到檔案衝突,且管理上也很不方便。 方法 2. 在同一目錄建立目標程式的符號連結 PowerShell: -------- New-Item -ItemType SymbolicLink -Path program1.exe -Target "C:\My Programs\pro gram1\program1.exe" -------- 符號連結的好處是簡單且方便管理。 但通過符號連結執行程式會因為找不到依賴的檔案 (例如 dll 檔) 而無法正常執行, 所以只適合用於單 exe 檔的程式。 或者,要為所有項目也建立符號連結。 但這可能會與其他程式的同名子目錄或檔案的符號連結衝突。 方法 3. 在同一目錄下建立執行目標程式的 bat 檔案 program1.bat: -------- @echo off "C:\My Programs\program1\program1.exe" %* exit /b %ERRORLEVEL% -------- bat 檔的好處是可以使用 set 命令預先設定必要的臨時環境參數。 但使用 bat 檔會遇到一個棘手的問題。 由於 bat 的 args 需要按照 cmd 的方式跳脫字元, 這導致我必須重寫現有 powershell 腳本裡的受影響的程式的執行命令。 或者必須在 bat 內就跳脫所有特殊字元, 但 cmd 貧弱的字串處理能力,還有一堆例外狀況,想到就讓人怯步… 以上三種方法無論是哪一種都有缺點 搞了半天還是乖乖往 PATH 內新增每個程式的目錄比較實際... 有沒有人知道更加漂亮的解決方式? -- Sent from PTTopia -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.231.152.70 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Windows/M.1714045005.A.193.html

62 則留言

smallreader, 1F
PATH為什麼會嫌太雜亂?太長再新增一行就好了吧

smallreader, 2F
啊 第二個方法 改用python就不怕跳脫字元了

smallreader, 3F
subprocess.run(["路徑"]+sys.argv[1:])
python 腳本的問題就是在 powershell 或 cmd 無法只使用 basename 呼叫並執行 PS> .\program # 執行名為 program 的可執行檔,例如 program.bat PS> python .\program.py # 執行 python 腳本 program.py 這會導致我要需要重寫我所有的 powershell 腳本

tonyhsie, 4F
正常都是1搭配3吧 大部分單一執行檔集中在一個目錄

tonyhsie, 5F
少部分一堆檔案的程式 改用批次檔 放在跟1同一目錄下
微軟自己的 winget 安裝 Console 程式就是在同一資料夾為所有 exe 檔建立符號連結 遺失依賴檔案的問題在 GitHub 上也是個開啟中的 Issue

tonyhsie, 6F
你如果會寫C#的話 可以不要用bat 自己寫個簡單的殼就好

tonyhsie, 7F
殼作的事就是單純切目錄跟傳遞參數而已

tonyhsie, 8F
然後把殼集中放在同一目錄下就好
這個方法稍微嘗試一下,目前還沒發現什麼問題

giacch, 9F
若是Windows, 就是安裝程式, 建立"捷徑"

giacch, 10F
純Console環境, 不是管理PATH, 就是要弄出類似"捷徑"的BAT

giacch, 11F
PATH新增C:\BIN, BIN底下建立各程式的BAT(當捷徑用)

giacch, 12F
BAT 內容包含 CD PathToProgram 與 Program.exe

giacch, 13F
更正 Program.exe %* 不要"號
問題不於如何執行目標程式,而是如何跳脫 args 中的所有特殊字元 例如在 powershell 用 ffmpeg 轉換影片格式 原始 ffmpeg.exe PS> .\ffmepg -i input.mp4 ^outpu.mkv # 實際輸出檔案名稱為 "^outpu.mkv" ffmpeg.bat PS> .\ffmpeg -i input.mp4 ^outpu.mkv # 實際輸出檔案名稱為 "outpu.mkv"
※ 編輯: falcon (118.231.152.70 臺灣), 04/26/2024 21:07:30

smallreader, 14F
https://i.imgur.com/cfRGvg2.png 寫寫存成ffmpeg.py
[問題] 安裝 Console 應用程式

smallreader, 15F
檔名.py可以直接呼叫檔名不帶.py 前面也不用叫python

smallreader, 16F
我這邊py檔案都是打basename就能執行的耶

smallreader, 17F
PS> (Get-Command ffmpeg).path =>也會回傳ffmpeg.py

smallreader, 18F
只要副檔名有註冊用python開啟就能這樣替代

giacch, 19F
# Program.ps1

giacch, 20F
Push-Location C:\Windows

giacch, 21F
& CMD.EXE /C "DIR NOTEPAD.EXE"

giacch, 22F
Pop-Location

giacch, 23F
我忘了要傳參數

giacch, 24F
& CMD.EXE /C DIR $ARGS # CMD 那行改這樣

giacch, 25F
Program.ps1 /B NOTEPAD.EXE # 這樣執行

smallreader, 26F
樓上..只要還經過cmd 答案就不及格

smallreader, 27F
欸...不對啊,所以方法3用ps寫不就解決了

smallreader, 28F
& "路徑" $args #存成.ps1
我發現搞錯一點了 還以為有名的參數一定要在 param() 內先宣告 不知道沒有宣告的都會被丟到 $args 那就奇怪了... 微軟的 winget 安裝 console 程式怎麼怎麼不用 .ps1 檔取代 links 目錄下的符號連結 這樣就不會因為程式找不到依賴檔案而無法正常執行了

giacch, 29F
對呀 都能執行 CMD 了 就執行你想執行的程式就好啦

smallreader, 30F
至於cd完全是多餘動作,不需要
※ 編輯: falcon (118.231.152.70 臺灣), 04/27/2024 00:59:44

falcon, 31F
雖然還不曉得會不會引發其他問題

falcon, 32F
總之,先感謝各位提供的方法

smallreader, 33F
更正,原來打basename認得到.py為可執行檔,是因為系

smallreader, 34F
統變數的PATHEXT裡面有包含.PY,然後雖然PATHEXT不包

smallreader, 35F
含.PS1,但因為殼層用PS,所以他自己會額外去找.PS1
對了 順便問題下 遇到 Linux 移植過來的程式,那些 share 的檔案要放哪裡? 通常是 config 或 preset 檔案 在 linux 中,我記得預設目錄位置是 /usr/local/share/<program name> 使用時只要給程式檔名或 basename 就可以了 但在 Windows 下如果不把工作目錄切過去 好像就只能使用絕對路徑了?
※ 編輯: falcon (118.231.152.70 臺灣), 04/27/2024 03:27:27

smallreader, 36F
你的意思是/usr/local/bin吧,這個它有在PATH裡面

smallreader, 37F
share就對到家目錄的AppData
試過許多路徑與環境變數都沒用 看起來有些程式並沒有為 Windows 設定程式資料目錄 只能在 .ps1 檔內自動修改目標參數的值了 param ([Alias('pre')][string]$preset) $programArgs = $args if (-not !$preset) { Push-Location 'C:\My Programs\program1\presets' $absConfigPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($preset) Pop-Location $programArgs += @('-pre', """$($absConfigPath)""") } & "C:\My Programs\program1\bin\program1.exe" $programArgs exit $lastExitCode
※ 編輯: falcon (118.231.152.70 臺灣), 04/28/2024 15:15:11

hunandy14, 38F
你那方法3 "cmd 的方式跳脫字元" 啥意思有範例嗎

hunandy14, 39F
然後環境被限制在cmd嗎? 如果是powershell的話有其他解

hunandy14, 69F
[問題] 安裝 Console 應用程式