SSブログ

Golang でショートカットを作成する。 [Golang]

Golangでショートカットを作成する方法 (vbsを利用)を見つけたので、
指定したFolderから再帰的にファイル名を取得し、ショートカットを作成してみる。
せっかくなので、ショートカット名はファイル名から置換できるようにし、
階層指定、Suffixを指定できるようにしている。
WindosはS-JISなので、その変換が必要。

↓参考
https://stackoverflow.com/questions/32438204/create-a-windows-shortcut-lnk-in-go


package main

import (
	"bytes"
	"flag"
	"fmt"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
)

func CreateShortcut(absPash string, symlink string, destination string) { // linkName string, target string, arguments string, directory string, description string, destination string) {
	// ショートカット作成 vbsを作成、実行することで ショートカットを実現する。
	// Golangから直接作成しようとすると、管理者権限が必要になる。それを避けている。
	var scriptTxt bytes.Buffer

	tmp := "set oWS = WScript.CreateObject(\"WScript.Shell\")\n"
	scriptTxt.WriteString(tmp)

	tmp = "sLinkFile = \"" + symlink + "\"\n"
	scriptTxt.WriteString(tmp)

	tmp = "Set oLink = oWS.CreateShortcut(sLinkFile)\n"
	scriptTxt.WriteString(tmp)

	tmp = "   oLink.TargetPath = \"" + absPash + "\"\n"
	scriptTxt.WriteString(tmp)

	tmp = "oLink.Save\n"
	scriptTxt.WriteString(tmp)
	//fmt.Print(scriptTxt.String())

	destination, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), destination)

	filename := fmt.Sprintf("lnk2%s.vbs", destination)
	filename, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), filename)

	//fmt.Print (filename)
	ioutil.WriteFile(filename, scriptTxt.Bytes(), 0777)
	cmd := exec.Command("wscript", filename)
	err := cmd.Run()
	cmd.Wait()

	if err != nil {
		fmt.Println(err)
	}
	cmd.Wait()
	os.Remove(filename)

	return
}

func GetFilelist(m map[string]string, path string, setDepth int, depth int) {
	// dir , _ := os.Getwd()	//カレントディレクトリ
	fis, err := ioutil.ReadDir(path) // file info's
	if err != nil {
		log.Fatal(err)
	}
	depth = depth + 1

	for num, fi := range fis {
		fullPath := path + "\\" + fi.Name()
		//absPath , _ := filepath.Abs(fi.Name())
		if setDepth == 0 || setDepth == depth {
			fmt.Println(depth, num, fullPath, fi.IsDir())
			if !(fi.IsDir()) {
				m[fi.Name()] = fullPath
			}
		}

		if fi.IsDir() { // directory の場合、isDir が true
			// Directory の場合再起呼び出し行う。VBAでは不可
			GetFilelist(m, path+"\\"+fi.Name(), setDepth, depth)
		}

	}
	//depth = depth - 1 // Global 変数ではないので、戻さなくてよい
	return
}

func main() {
	/*
		目的:
			パワポなどからハイパーリンクを伝って、本体を呼び出すためのリンクを作成する。
			直接リンクすればよいが、ファイル名にリビジョン情報が含まれていた場合、ハイパーリンクを張りなおすのは
			手間になるので、リビジョン情報を削除したショートカットを作成し、そのショートカットにハイパーリンクを張ることで
			パワポの情報は更新せずにショートカットを再作成することで対応することで解決することを目的に、
			このショートカット作成スクリプトを作成した。
			よって、リビジョン情報の削除を 正規表現で削除できるようにしている。引数で引用できる。

		スクリプト設計方針:
			Dir関数でターゲットディレクトリ内のファイルとディレクトリ名を得る
			ディレクトリの場合は再起呼び出しで中に入り、さらにファイル名とディレクトリを取得する。
			深さの階層指定を行い、その階層のファイル名と、FullPathのリスト(Map)を作成する。
			深さに0を指定した場合、階層指定は行わずすべてを集める。
			引数の exp で指定した ファイル名を正規表現で置換(削除)する。
			これは、Revisionが変わっても、ショートカット名を同じにする事を目的にしている。

			Mapからファイル名とFullPathを取り出し、Suffixが指定したものだけショートカットを作成する。
			ショートカット作成は vbs を作成し対応している。Golangから直接ショートカット作成は難しい。(できない)


	*/

	var (
		// arg parse 設定
		Path  = flag.String("i", ".", "target  directory path")
		Depth = flag.Int("d", 2, "ファイルパスの深さの設定 0:すべての階層を指定")
		regEX = flag.String("exp", "_R.+\\.", "正規表現 文字列として記載する")
		// 引数は文字列とするため \\ が必要
		suffix = flag.String("suf", "ppt pptx", "サフィックスを指定 * の場合はすべて")
	)

	flag.Parse()

	tgtPath, _ := filepath.Abs(*Path) // "."
	setDepth := *Depth                // 2  , 0:すべての階層から収集する

	re := regexp.MustCompile(*regEX)
	// regEX := `_R.+\.`	// ` is backticks  , no ' single quote)

	m := make(map[string]string) // make で初期化、Key にファイル名、Itemにフルパスを格納する

	GetFilelist(m, tgtPath, setDepth, 0) // ファイル名を取得し、Mapに格納して戻る。

	s := strings.Split(*suffix, " ")
	fmt.Println(s)
	// Mapからファイル名、FullPathを取り出し、指定したSuffixの物だけショートカットを作成する。
	for fileName, Path := range m {
		for _, tmp := range s {
			//fmt.Println(tmp)
			if strings.HasSuffix(fileName, tmp) || tmp == "*" {
				fmt.Print(fileName, "\t", Path)
				symlink := re.ReplaceAllString(fileName, ".") + ".lnk"
				fmt.Println("\t" + symlink)

				Path, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), Path)
				symlink, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), symlink)
				CreateShortcut(Path, symlink, "temp")
			}
		}
	}

}


nice!(0)  コメント(0) 
共通テーマ:パソコン・インターネット

GolangでMsgboxをPopupさせる [Golang]

golang で msgboxをPopupさせる。

// https://github.com/golang/go/wiki/WindowsDLLs
package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

func main() {
	var mod = syscall.NewLazyDLL("user32.dll")
	var proc = mod.NewProc("MessageBoxW")
	var MB_YESNOCANCEL = 0x00000003

	ret, _, _ := proc.Call(0,
		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("This test is Done."))),
		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Done Title"))),
		uintptr(MB_YESNOCANCEL))
	fmt.Printf("Return: %d\n", ret)

}




ほかの物の調査結果


nice!(0)  コメント(0) 

excel から使用シートを決定するアルゴ [アルゴ]

/*
excel から使用シートを決定するアルゴ

すべてのシート名をGet
1.すべてのシートから key word が含まれているものを選択
履歴、変更、不要、OLD、Old,old が含まれれている場合は除外

2.(1)で見つからなかった場合
Sheet1の名称を選択
履歴、変更、不要、OLD、Old,old が含まれれている場合は除外

3.(1)、(2)
アクティブシートを選択
履歴、変更、不要、OLD、Old,old が含まれれている場合は除外
4.(1)、(2)、(3)で見つからなかった場合エラー応答

*/
nice!(0)  コメント(0) 
共通テーマ:日記・雑感

Excel xlsx,xlsmからcsvを生成する。Win用にSJIS変換を追加 [Excel]

// Copyright 2020-, The ExcelDir2csv
//  T.Sanono
// All rights reserved.
// ExeclDir2csv.go
//
// tealeg/xlsx では ActiveSheetを得られなかったので、excelizeを使用している
// xlsx2csv では 小細工が効かない。デリミタが固定、 %sで ""で囲まれた
// 指定したDirectoryからすべてのxlsx,xlsmを集めて csv ディレクトリに出力する。
//
// go run ExcelDir2csv.go [-i .\excel] [-o .\csv] [-d ","]

package main

import (
	"flag"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"
)

func getActiveSheetName(f *excelize.File) string {
	idx := f.GetActiveSheetIndex()
	fname := f.GetSheetName(idx)
	return fname
}
func fileNameCheck(fileName string) bool {
	if !(strings.HasSuffix(fileName, "xlsx") || (strings.HasSuffix(fileName, "xlsm"))) {
		return false
	}
	if strings.HasPrefix(fileName, "~$") {
		return false
	}
	re := regexp.MustCompile("不要")
	if re.MatchString(fileName) {
		return false
	}
	return true
}

var (
	// arg parse 設定
	inFolder  = flag.String("i", "./excel", "input  directory option")
	outFolder = flag.String("o", "./csv", "output directory option")
	delimiter = flag.String("d", ",", "delimiter option       ")
	encode    = flag.String("encode","sjis","encoding/japanese")
)

func main() {
	// 初期設定
	// ======================
	// inFolder		:= "./excel"
	// outFolder	:= "./csv"
	// delimiter	:= ","
	// =======================
	flag.Parse()
	ExcelDir2csv(*inFolder, *outFolder, *delimiter, *encode)
}

func ExcelDir2csv(inFolder string , outFolder string , delimiter string , encode string ) {
	/*
	   1.Folder内のファイル名を収集

	   2.フォルダーを順にxlsx、xlsm のみを選択しながらファイルを開く
	   3.シート名を収集してシート名に  port_listがあれば、そのシート名を返す。
	   	なければアクティブシートを返す。
	   4.csvを出力する。
	   5.2に戻る。

	*/

	var tmp string
	// フォルダー内のファイル名を収集
	files, err := ioutil.ReadDir(inFolder)
	if err != nil {
		s := "Error: Folder Not Found : " + inFolder
		fmt.Println(s)
		os.Exit(1)
	}

	for _, fs := range files {
		fileName := fs.Name()

		// 得られたファイル名がxlsx、slsmかどうかのチェック
		if !fileNameCheck(fileName) {
			continue
		}

		// ファイルをOpen
		tmp = inFolder + "/" + fileName
		fmt.Printf("Input File Name:%20s , ", tmp)
		f, err := excelize.OpenFile(tmp)
		if err != nil {
			println("File not found")
			os.Exit(1)
		}

		// アクティブシートGet
		sheetName := getActiveSheetName(f)
		fmt.Printf("Sheet Name:%20s ", sheetName)

		// サフィックスを csv に変換
		tmp = fileName
		tmp = strings.Replace(tmp, ".xlsx", ".csv", -1)
		tmp = strings.Replace(tmp, ".xlsm", ".csv", -1)
		tmp = outFolder + "/" + tmp
		fmt.Printf("Output File Name:%30s \n", tmp)
		file, err := os.Create(tmp)

		// シートからcsv に変換
		// Get all the rows in the Sheet.
		rows, err := f.GetRows(sheetName)
		if err != nil {
			fmt.Printf("Error!")
			log.Fatal(err)
		}
		defer file.Close()

		for _, row := range rows { // rows is slice type
			//fmt.Printf("%T type ",row)
			//fmt.Printf("%v \n",row[:]) // [Sheet3 a1 b5][Sheet4 a2 b6]
			out := strings.Join(row, delimiter) + "\n" // スライスを delimiter で区切ってつなぐ
			if encode == "sjis" {
				out, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), out)
			}
			file.Write(([]byte)(out))

		}
		file.Close()
	}
}

タグ:Golang Excel csv
nice!(0)  コメント(0) 

Excel xlsx,slsmからcsvを生成する [Excel]

ExcelのCSVを生成するためのGolang、ActiveSheetから生成するために、作成
// Copyright 2020-, The ExcelDir2csv
// Sanono
// All rights reserved.
// ExeclDir2csv.go
//
// tealeg/xlsx では ActiveSheetを得られなかったので、excelizeを使用している
// xlsx2csv では 小細工が効かない。デリミタが固定、 %sで ""で囲まれたもの
//
// 指定したDirectoryからすべてのxlsx,slsmを集めて csv ディレクトリに出力する。
//
// go run ExcelDir2csv.go [-i .\excel] [-o .\csv] [-d ","]

package main

import (
"os"
"io/ioutil"
"log"
"fmt"
"strings"
"regexp"
"flag"
"github.com/360EntSecGroup-Skylar/excelize"

)

func getActiveSheetName(f *excelize.File) string {
idx:=f.GetActiveSheetIndex()
fname :=f.GetSheetName(idx)
return fname
}
func fileNameCheck(fileName string) bool{
if !((strings.HasSuffix(fileName, "xlsx")|| (strings.HasSuffix(fileName,"xlsm")))){
return false
}
if (strings.HasPrefix(fileName,"~$")) {
return false
}
re := regexp.MustCompile("不要")
if (re.MatchString(fileName)){
return false
}
return true
}

var (
// arg parse 設定
inFolder = flag.String("i","./excel" ,"input directory option")
outFolder = flag.String("o","./csv" ,"output directory option")
delimiter = flag.String("d","," ,"delimiter option ")
)

func main (){
// 初期設定
// ======================
// inFolder := "./excel"
// outFolder := "./csv"
// delimiter := ","
// =======================
flag.Parse()
ExcelDir2csv(*inFolder,*outFolder,*delimiter)
}

func ExcelDir2csv(inFolder string ,outFolder string ,delimiter string ) {
/*
1.Folder内のファイル名を収集

2.フォルダーを順にxlsx、xlsm のみを選択しながらファイルを開く
3.シート名を収集してシート名に  port_listがあれば、そのシート名を返す。
なければアクティブシートを返す。
4.csvを出力する。
5.2に戻る。

*/

var tmp string
// フォルダー内のファイル名を収集
files, err := ioutil.ReadDir(inFolder)
if err != nil {
s:= "Error: Folder Not Found : " + inFolder
fmt.Println(s)
os.Exit(1)
}

for _, fs := range files {
fileName := fs.Name()

// 得られたファイル名がxlsx、slsmかどうかのチェック
if !fileNameCheck(fileName) {
continue
}

// ファイルをOpen
tmp = inFolder + "/" + fileName
fmt.Printf("Input File Name:%20s , " , tmp)
f, err := excelize.OpenFile(tmp)
if err != nil {
println("File not found")
os.Exit(1)
}

// アクティブシートGet
sheetName := getActiveSheetName(f)
fmt.Printf("Sheet Name:%20s " , sheetName)

// サフィックスを csv に変換
tmp = fileName
tmp = strings.Replace(tmp ,".xlsx",".csv",-1)
tmp = strings.Replace(tmp ,".xlsm",".csv",-1)
tmp = outFolder + "/" + tmp
fmt.Printf("Output File Name:%30s \n" ,tmp )
file ,err := os.Create(tmp)

// シートからcsv に変換
// Get all the rows in the Sheet.
rows, err := f.GetRows(sheetName)
if err !=nil{
fmt.Printf("Error!")
log.Fatal( err)
}
defer file.Close()

for _, row := range rows { // rows is slice type
//fmt.Printf("%T type ",row)
//fmt.Printf("%v \n",row[:]) // [Sheet3 a1 b5][Sheet4 a2 b6]
out:=strings.Join(row,delimiter) + "\n" // スライスを delimiter で区切ってつなぐ
file.Write(([]byte)(out))

}
file.Close()
}
}


nice!(0)  コメント(0) 

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。