Skip to content

Commit

Permalink
Open log from context menu
Browse files Browse the repository at this point in the history
  • Loading branch information
balazsgrill committed Aug 20, 2024
1 parent b4d20ce commit 8c7fcb7
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
run: go generate ./...

- name: Build
run: go build -o potatodrive.exe ./cmd/main
run: go build -o potatodrive.exe -ldflags="-H windowsgui" ./cmd/main
- uses: actions/upload-artifact@v4
with:
name: potatodrive.exe
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[subbodule "winrt-go"]
path = winrt-go
url = https://github.com/balazsgrill/winrt-go.git
5 changes: 4 additions & 1 deletion cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ func main() {
log.Print(err)
return
}
ui := createUI(mgr.Logger)
ui := createUI(UIContext{
Logger: mgr.Logger,
LogFile: mgr.logfilepath,
})
defer ui.ni.Dispose()

keys, _ := mgr.InstanceList()
Expand Down
12 changes: 7 additions & 5 deletions cmd/main/mgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ import (

type Manager struct {
zerolog.Logger
logf io.Closer
logf io.Closer
logfilepath string

parentkey registry.Key

keylist []string
instances map[string]io.Closer
}

func initLogger() (zerolog.Logger, io.Closer) {
func initLogger() (string, zerolog.Logger, io.Closer) {
cachedir, err := os.UserCacheDir()
if err != nil {
panic(err)
Expand All @@ -34,11 +35,12 @@ func initLogger() (zerolog.Logger, io.Closer) {
}

logfile := "potatodrive.log"
logf, err := os.OpenFile(filepath.Join(logfolder, logfile), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
logfilepath := filepath.Join(logfolder, logfile)
logf, err := os.OpenFile(logfilepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
return log.Output(logf).With().Timestamp().Logger(), logf
return logfilepath, log.Output(logf).With().Timestamp().Logger(), logf
}

func startInstance(parentkey registry.Key, keyname string, logger zerolog.Logger, statecallback func(error)) (io.Closer, error) {
Expand Down Expand Up @@ -80,7 +82,7 @@ func New() (*Manager, error) {
m := &Manager{
instances: make(map[string]io.Closer),
}
m.Logger, m.logf = initLogger()
m.logfilepath, m.Logger, m.logf = initLogger()
var err error
m.parentkey, err = registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\PotatoDrive", registry.QUERY_VALUE|registry.READ)
if err != nil {
Expand Down
26 changes: 20 additions & 6 deletions cmd/main/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
_ "image/png"

"github.com/balazsgrill/potatodrive/assets"
"github.com/balazsgrill/potatodrive/win"
"github.com/lxn/walk"
"github.com/rs/zerolog"
"golang.org/x/sys/windows"
)

//go:generate rsrc -manifest .\main.exe.manifest -o rsrc.syso
Expand All @@ -18,8 +20,14 @@ type UI struct {
ni *walk.NotifyIcon
}

func createUI(logger zerolog.Logger) *UI {
type UIContext struct {
Logger zerolog.Logger
LogFile string
}

func createUI(context UIContext) *UI {
ui := &UI{}
logger := context.Logger

// We need either a walk.MainWindow or a walk.Dialog for their message loop.
// We will not make it visible in this example, though.
Expand Down Expand Up @@ -73,6 +81,17 @@ func createUI(logger zerolog.Logger) *UI {
}
})

openLogAction := walk.NewAction()
if err := openLogAction.SetText("&Open Log"); err != nil {
logger.Fatal().Err(err).Send()
}
openLogAction.Triggered().Attach(func() {
win.OpenFile(windows.Handle(ui.MainWindow.Handle()), context.LogFile)
})
if err := ui.ni.ContextMenu().Actions().Add(openLogAction); err != nil {
logger.Fatal().Err(err).Send()
}

// We put an exit action into the context menu.
exitAction := walk.NewAction()
if err := exitAction.SetText("E&xit"); err != nil {
Expand All @@ -88,11 +107,6 @@ func createUI(logger zerolog.Logger) *UI {
logger.Fatal().Err(err).Send()
}

// Now that the icon is visible, we can bring up an info balloon.
if err := ui.ni.ShowInfo("Walk NotifyIcon Example", "Click the icon to show again."); err != nil {
logger.Fatal().Err(err).Send()
}

ui.Logger = logger.Hook(zerolog.HookFunc(func(e *zerolog.Event, level zerolog.Level, msg string) {
switch level {
case zerolog.ErrorLevel:
Expand Down
3 changes: 1 addition & 2 deletions win/cfapi/filesystem/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ func (instance *VirtualizationInstance) Close() error {
return win.ErrorByCode(hr)
}

hr = cfapi.CfUnregisterSyncRoot(win.GetPointer(instance.rootPath))
return win.ErrorByCode(hr)
return nil
}

func (instance *VirtualizationInstance) PerformSynchronization() error {
Expand Down
27 changes: 27 additions & 0 deletions win/cfapi/filesystem/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"
"time"

"github.com/google/uuid"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

Expand All @@ -29,6 +30,12 @@ func newTestInstance(t *testing.T) *testInstance {
location := t.TempDir()
os.RemoveAll(location)
os.MkdirAll(location, 0x777)
uid := uuid.NewMD5(uuid.UUID{}, []byte(location))
id := win.BytesToGuid(uid[:])
err := filesystem.RegisterRootPathSimple(*id, location)
if err != nil {
t.Fatal(err)
}
return &testInstance{
t: t,
location: location,
Expand All @@ -37,6 +44,10 @@ func newTestInstance(t *testing.T) *testInstance {
}
}

func (i *testInstance) Close() {
filesystem.UnregisterRootPathSimple(i.location)
}

func (i *testInstance) start() {
started := make(chan bool)
var err error
Expand Down Expand Up @@ -74,6 +85,7 @@ func (i *testInstance) stop() {

func TestExistingFileOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()

data := []byte("something")
filename := "test.txt"
Expand Down Expand Up @@ -101,6 +113,7 @@ func TestExistingFileOnBackend(t *testing.T) {

func TestFileCreation(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()
defer instance.stop()

Expand Down Expand Up @@ -131,6 +144,7 @@ func TestFileCreation(t *testing.T) {

func TestUpdateExistingFileOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()

data := "something"
filename := "test.txt"
Expand Down Expand Up @@ -170,6 +184,7 @@ func TestUpdateExistingFileOnBackend(t *testing.T) {

func TestDeleteExistingFileOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
data := "something"
filename := "test.txt"
err := afero.WriteFile(instance.fs, filename, []byte(data), 0x777)
Expand Down Expand Up @@ -205,6 +220,7 @@ func TestDeleteExistingFileOnBackend(t *testing.T) {

func TestListFiles(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()
defer instance.stop()

Expand Down Expand Up @@ -251,6 +267,7 @@ func TestListFiles(t *testing.T) {

func TestExistingFolderOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()

foldername := "test"
instance.fs.Mkdir(foldername, 0x777)
Expand All @@ -270,6 +287,7 @@ func TestExistingFolderOnBackend(t *testing.T) {

func TestFolderCreation(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()
defer instance.stop()

Expand All @@ -296,6 +314,7 @@ func TestFolderCreation(t *testing.T) {

func TestCreatedOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()
defer instance.stop()

Expand Down Expand Up @@ -324,6 +343,7 @@ func TestCreatedOnBackend(t *testing.T) {

func TestChangedOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()

data := []byte("something")
filename := "test.txt"
Expand Down Expand Up @@ -369,6 +389,7 @@ func TestChangedOnBackend(t *testing.T) {

func TestDeletedOnBackend(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()
defer instance.stop()
data := []byte("something")
Expand Down Expand Up @@ -404,6 +425,7 @@ func TestDeletedOnBackend(t *testing.T) {

func TestUpdatedLocallyWhileOffline(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()

data := []byte("something")
Expand Down Expand Up @@ -442,6 +464,7 @@ func TestUpdatedLocallyWhileOffline(t *testing.T) {
func TestRemoveFolder(t *testing.T) {
foldername := "test"
instance := newTestInstance(t)
defer instance.Close()
err := instance.fs.Mkdir(foldername, 0x777)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -481,6 +504,7 @@ func TestRemoveFolder(t *testing.T) {

func TestDeletedOnBackendWhileOffline(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()

data := []byte("something")
Expand Down Expand Up @@ -527,6 +551,7 @@ func TestDeletedOnBackendWhileOffline(t *testing.T) {

func TestDeletedLocallyWhileOffline(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()

data := []byte("something")
Expand Down Expand Up @@ -569,6 +594,7 @@ func TestDeletedLocallyWhileOffline(t *testing.T) {

func TestConflictWhileOfflineLocalNewer(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()

data := []byte("something")
Expand Down Expand Up @@ -621,6 +647,7 @@ func TestConflictWhileOfflineLocalNewer(t *testing.T) {

func TestConflictWhileOfflineRemoteNewer(t *testing.T) {
instance := newTestInstance(t)
defer instance.Close()
instance.start()

data := []byte("something")
Expand Down
38 changes: 33 additions & 5 deletions win/cfapi/filesystem/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package filesystem

import (
"runtime"
"syscall"
"unsafe"

"github.com/balazsgrill/potatodrive/win"
"github.com/balazsgrill/potatodrive/win/cfapi"
"github.com/go-ole/go-ole"
"github.com/rs/zerolog/log"
"github.com/saltosystems/winrt-go"
"github.com/saltosystems/winrt-go/windows/foundation"
"github.com/saltosystems/winrt-go/windows/storage"
Expand All @@ -30,6 +34,33 @@ func getFolder(folder string) (*storage.IStorageFolder, error) {
return (*storage.IStorageFolder)(unsafe.Pointer(ptr)), err
}

func RegisterRootPathSimple(id syscall.GUID, rootPath string) error {
var registration cfapi.CF_SYNC_REGISTRATION
registration.ProviderId = id
registration.ProviderName = win.GetPointer("PotatoDrive")
registration.ProviderVersion = win.GetPointer("0.1")
registration.StructSize = uint32(unsafe.Sizeof(registration))
var policies cfapi.CF_SYNC_POLICIES
policies.StructSize = uint32(unsafe.Sizeof(policies))
policies.Hydration.Primary = cfapi.CF_HYDRATION_POLICY_FULL
policies.Hydration.Modifier = cfapi.CF_HYDRATION_POLICY_MODIFIER_AUTO_DEHYDRATION_ALLOWED
policies.Population.Primary = cfapi.CF_POPULATION_POLICY_ALWAYS_FULL
policies.InSync = cfapi.CF_INSYNC_POLICY_TRACK_ALL
policies.HardLink = cfapi.CF_HARDLINK_POLICY_NONE
policies.PlaceholderManagement = cfapi.CF_PLACEHOLDER_MANAGEMENT_POLICY_DEFAULT
log.Print("Registering sync root")
hr := cfapi.CfRegisterSyncRoot(win.GetPointer(rootPath), &registration, &policies, cfapi.CF_REGISTER_FLAG_NONE)
if hr != 0 {
return win.ErrorByCode(hr)
}
return nil
}

func UnregisterRootPathSimple(rootPath string) error {
hr := cfapi.CfUnregisterSyncRoot(win.GetPointer(rootPath))
return win.ErrorByCode(hr)
}

func RegisterRootPath(id string, rootPath string) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
Expand All @@ -50,16 +81,13 @@ func RegisterRootPath(id string, rootPath string) error {
if err == nil && existing != nil {
// Already registered
eid, _ := existing.GetId()
/*if eid == id {
// No need to register again
return nil
} else {*/
// TODO should not register again, but it fails if I do so
// unregister first
err = provider.StorageProviderSyncRootManagerUnregister(eid)
if err != nil {
return err
}
//}

}

info.SetAllowPinning(true)
Expand Down
15 changes: 15 additions & 0 deletions win/openfile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package win

import "golang.org/x/sys/windows"

func OpenFile(handle windows.Handle, path string) error {
pathp, err := windows.UTF16PtrFromString(path)
if err != nil {
return err
}
verpp, err := windows.UTF16PtrFromString("open")
if err != nil {
return err
}
return windows.ShellExecute(handle, verpp, pathp, nil, nil, 1)
}
1 change: 1 addition & 0 deletions winrt-go
Submodule winrt-go added at ed5621

0 comments on commit 8c7fcb7

Please sign in to comment.