Skip to content

Instantly share code, notes, and snippets.

@niski84
Last active September 14, 2023 01:54
Show Gist options
  • Save niski84/f3263e0f18d16aba5cf4fa59f0a03d91 to your computer and use it in GitHub Desktop.
Save niski84/f3263e0f18d16aba5cf4fa59f0a03d91 to your computer and use it in GitHub Desktop.
discover if 7z installed on windows
// Find7zLocation checks for the existence of the 7z executable and returns its path and version.
func Find7zLocation() (string, string, error) {
// Check if 7z is in the PATH
path, err := exec.LookPath("7z")
if err == nil {
// Run '7z i' to get version information
cmd := exec.Command(path, "i")
output, err := cmd.CombinedOutput()
if err != nil {
return "", "", err
}
versionInfo := strings.Split(string(output), "\n")[1] // Assuming the version is on the second line
return path, versionInfo, nil
}
// Check common installation directories for 7z on Windows
commonPaths := []string{
"C:\\Program Files\\7-Zip\\7z.exe",
"C:\\Program Files (x86)\\7-Zip\\7z.exe",
}
for _, commonPath := range commonPaths {
if _, err := os.Stat(commonPath); err == nil {
cmd := exec.Command(commonPath, "i")
output, err := cmd.CombinedOutput()
if err != nil {
return "", "", err
}
versionInfo := strings.Split(string(output), "\n")[1] // Assuming the version is on the second line
return commonPath, versionInfo, nil
}
}
return "", "", fmt.Errorf("7z executable not found")
}
// z7Unzip uses the 7-Zip command-line utility to unzip a file.
func z7Unzip(execPath, src, dest string) ([]string, error) {
var filePaths []string
// Use os/exec to execute 7z command from teh given executable path
cmd := exec.Command(execPath, "x", src, fmt.Sprintf("-o%s", dest), "-aoa")
// Display teh command before execution
fmt.Println("Executing:", cmd.String())
var stdoutBuf, stderrBuf bytes.Buffer
cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
cmd.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
// Start the 7z process
if err := cmd.Start(); err != nil {
return nil, err
}
// Wait for teh 7z process to finish
if err := cmd.Wait(); err != nil {
return nil, err
}
outStr, errStr := string(stdoutBuf.Bytes()), string(stderrBuf.Bytes())
fmt.Printf("\nout:\n%s\nerr:\n%s\n", outStr, errStr)
// Walk teh directory recursivley and gather all teh file paths
err := filepath.Walk(dest, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Skip the root directory
if path != dest {
filePaths = append(filePaths, path)
}
return nil
})
if err != nil {
return nil, err
}
return filePaths, nil
}
func z7UnzipWithLogging(execPath, src, dest, logDir string) ([]string, error) {
var filePaths []string
var wg sync.WaitGroup
// Generate teh timestamped log filename
currentTime := time.Now()
timestamp := currentTime.Format("20060102T150405") // YYYYMMDDTHHMMSS
logFileName := fmt.Sprintf("7z_log_%s.txt", timestamp)
logFilePath := filepath.Join(logDir, logFileName)
// Create log file in teh specified logDir
logFile, err := os.Create(logFilePath)
if err != nil {
return nil, err
}
defer logFile.Close()
// Create and start teh command
cmd := exec.Command(execPath, "x", src, fmt.Sprintf("-o%s", dest), "-aoa", "-bb2")
cmd.Stdout = logFile
cmd.Stderr = logFile
// Display teh command before execution
fmt.Println("Executing:", cmd.String())
done := make(chan struct{})
if err := cmd.Start(); err != nil {
return nil, err
}
wg.Add(1)
// Simulate a 'tail -f' to display teh log content in real time
go func() {
defer wg.Done()
f, err := os.Open(logFilePath)
if err != nil {
fmt.Println("Error opening log file:", err)
return
}
defer f.Close()
r := bufio.NewReader(f)
for {
line, _, err := r.ReadLine()
if err != nil {
select {
case <-done:
return
default:
time.Sleep(1 * time.Second)
continue
}
}
fmt.Println(string(line))
}
}()
// Wait for teh 7z process to finish
if err := cmd.Wait(); err != nil {
return nil, err
}
close(done)
wg.Wait()
// Walk teh directory and gather all teh file paths
err = filepath.Walk(dest, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Skip teh root directory
if path != dest {
filePaths = append(filePaths, path)
}
return nil
})
if err != nil {
return nil, err
}
return filePaths, nil
}
func main() {
path, version, err := Find7zLocation()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("7z found at: %s\n", path)
fmt.Printf("Version info: %s\n", version)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment