I want to disable quick edit mode in Golang to avoid my terminal getting block by a user click.
For that I use the official library golang.org/x/sys/windows.
I want to disable QUICK_EDIT_MODE & enable EXTENDED_FLAGS as describe by the official microsoft doc. When I use the code snippet below, I'm getting an error at set The parameter is incorrect.
I'm running it in CMD or Powershell I get the same error there. And I don't really know what is missing there. I'm on Windows 10 v20H2 19042.1586 if that matters.
Code Snippet
import (
"os"
"golang.org/x/sys/windows"
)
...
func SetupConsole() {
winConsole := windows.Handle(os.Stdout.Fd())
var mode uint32
err := windows.GetConsoleMode(winConsole, &mode)
if err != nil {
log.Println(err)
}
log.Printf("%d", mode) <--- 3
// Disable this mode
mode &^= windows.ENABLE_QUICK_EDIT_MODE
// Enable this mode
mode |= windows.ENABLE_EXTENDED_FLAGS
log.Printf("%d", mode) <--- 131
err = windows.SetConsoleMode(winConsole, mode)
if err != nil {
log.Println(err) <--- This fails: The parameter is incorrect.
}
}
EDIT: See Answer below
func SetupConsole() {
winConsole := windows.Handle(os.Stdin.Fd()) <--- Was wrong here
var mode uint32
err := windows.GetConsoleMode(winConsole, &mode)
if err != nil {
log.Println(err)
}
log.Printf("%d", mode)
// Disable this mode
mode &^= windows.ENABLE_QUICK_EDIT_MODE
// Enable this mode
mode |= windows.ENABLE_EXTENDED_FLAGS
log.Printf("%d", mode)
err = windows.SetConsoleMode(winConsole, mode)
if err != nil {
log.Println(err)
}
}
I see two issues.
First you should be using Stdin instead of Stdout. You can also just pass in windows.Stdin into the Get/SetConsole mode and skip the Fd() call and casting.
Second, to disable it you just need to toggle the windows.ENABLE_QUICK_EDIT_MODE flag.
The combination of using Stdout & ENABLE_EXTENDED_FLAGS together is what resulted in the error returing from SetConsoleMode
Related
I'd like to connect from Go to the running instance of the Memgraph database. I'm using Docker and I've installed the Memgraph Platform. What exactly do I need to do?
The procedure for connecting fro Go to Memgraph is rather simple. For this you need to use Bolt protocol. Here are the needed steps:
First, create a new directory for your app, /MyApp, and position yourself in it. Next, create a program.go file with the following code:
package main
import (
"fmt"
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
)
func main() {
dbUri := "bolt://localhost:7687"
driver, err := neo4j.NewDriver(dbUri, neo4j.BasicAuth("username", "password", ""))
if err != nil {
panic(err)
}
// Handle driver lifetime based on your application lifetime requirements driver's lifetime is usually
// bound by the application lifetime, which usually implies one driver instance per application
defer driver.Close()
item, err := insertItem(driver)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", item.Message)
}
func insertItem(driver neo4j.Driver) (*Item, error) {
// Sessions are short-lived, cheap to create and NOT thread safe. Typically create one or more sessions
// per request in your web application. Make sure to call Close on the session when done.
// For multi-database support, set sessionConfig.DatabaseName to requested database
// Session config will default to write mode, if only reads are to be used configure session for
// read mode.
session := driver.NewSession(neo4j.SessionConfig{})
defer session.Close()
result, err := session.WriteTransaction(createItemFn)
if err != nil {
return nil, err
}
return result.(*Item), nil
}
func createItemFn(tx neo4j.Transaction) (interface{}, error) {
records, err := tx.Run(
"CREATE (a:Greeting) SET a.message = $message RETURN 'Node ' + id(a) + ': ' + a.message",
map[string]interface{}{"message": "Hello, World!"})
// In face of driver native errors, make sure to return them directly.
// Depending on the error, the driver may try to execute the function again.
if err != nil {
return nil, err
}
record, err := records.Single()
if err != nil {
return nil, err
}
// You can also retrieve values by name, with e.g. `id, found := record.Get("n.id")`
return &Item{
Message: record.Values[0].(string),
}, nil
}
type Item struct {
Message string
}
Now, create a go.mod file using the go mod init example.com/hello command.
I've mentioned the Bolt driver earlier. You need to add it with go get github.com/neo4j/neo4j-go-driver/v4#v4.3.1. You can run your program with go run .\program.go.
The complete documentation is located at Memgraph site.
I'm iterating through a mounted folder via filePath.Walk method in golang, but it returns the hidden files as well. I have to skip those hidden files.
For MaxOS and Linux, we can detect hidden file via .prefix in the filename, but for windows, when I'm trying to us this method GetFileAttributes, provided by "syscall", it's not detecting these methods and throwing an error.
Using below method to fetch the file
err := filepath.Walk(prefix, func(docPath string, f os.FileInfo, err error) error {
Below is how I'm trying to detect the hidden files
import (
"runtime"
"syscall"
)
func IsHiddenFile(filename string) (bool, error) {
if runtime.GOOS == "windows" {
pointer, err := syscall.UTF16PtrFromString(filename)
if err != nil {
return false, err
}
attributes, err := syscall.GetFileAttributes(pointer)
if err != nil {
return false, err
}
return attributes&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil
} else {
// unix/linux file or directory that starts with . is hidden
if filename[0:1] == "." {
return true, nil
}
}
return false, nil
}
Error :
.../ undefined: syscall.UTF16PtrFromString
.../ undefined: syscall.GetFileAttributes
.../ undefined: syscall.FILE_ATTRIBUTE_HIDDEN
I added this // +build windows in the start of the file before package name as suggested here : syscall variables undefined but it's sill not working and throwing the same error.
I need to know if go provides some common method to detect if a file is hidden or not? Or is there a way I can fetch all the files/folder in some mounted directory without receiving hidden files in the first place?
Really looking forward on receiving some feedback here, thanks.
EDIT : Fixed the above mentioned issue (please refer to the comments below), I also wants to know how can we detect the hidden file when we are connected with the remote server (SMB), the remoter system could be running any OS, and we compile these method based on the system it's running on. How can we detect Hidden files in that scenario ?
Conditional compilation is the right way to go, but it applies at source file level, so you need two separate files.
For example:
hidden_notwin.go:
//go:build !windows
package main
func IsHiddenFile(filename string) (bool, error) {
return filename[0] == '.', nil
}
hidden_windows.go:
//go:build windows
package main
import (
"syscall"
)
func IsHiddenFile(filename string) (bool, error) {
pointer, err := syscall.UTF16PtrFromString(filename)
if err != nil {
return false, err
}
attributes, err := syscall.GetFileAttributes(pointer)
if err != nil {
return false, err
}
return attributes&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil
}
Note that //go:build windows tag above is optional - the _windows source file suffix does the magic already. For more details see go command - Build constraints.
I have this module that use Google Cloud API to retrieve a list of all running Virtual Machine instances for a particular project. I'm new to Go, and followed the intro tutorial to help me out. I'm still trying to debug my code but no luck.
The problem is I'm able to communicate to Google Cloud API and pass authentication but that is all I can get through
compute.go module:
compute.go is able to communicate to Google Cloud servers and pass authentication (I'm not getting an auth error)
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
// [START compute_instances_list_all]
import (
"context"
"fmt"
"io"
compute "cloud.google.com/go/compute/apiv1"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
"google.golang.org/protobuf/proto"
)
// listAllInstances prints all instances present in a project, grouped by their zone.
func ListAllInstances(w io.Writer, projectID string) error {
// projectID := "your_project_id"
ctx := context.Background()
instancesClient, err := compute.NewInstancesRESTClient(ctx)
// instancesClient, err := compute.NewInstancesRESTClient(ctx, option.WithCredentialsFile(`C:\path\to\jsonkey.json`))
if err != nil {
return fmt.Errorf("NewInstancesRESTClient: %v", err)
}
defer instancesClient.Close()
// Use the `MaxResults` parameter to limit the number of results that the API returns per response page.
req := &computepb.AggregatedListInstancesRequest{
Project: projectID,
MaxResults: proto.Uint32(6),
}
it := instancesClient.AggregatedList(ctx, req)
fmt.Fprintf(w, "Instances found:\n")
// Despite using the `MaxResults` parameter, you don't need to handle the pagination
// yourself. The returned iterator object handles pagination
// automatically, returning separated pages as you iterate over the results.
for {
pair, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return err
}
instances := pair.Value.Instances
if len(instances) > 0 {
fmt.Fprintf(w, "%s\n", pair.Key)
for _, instance := range instances {
fmt.Fprintf(w, "- %s %s\n", instance.GetName(), instance.GetMachineType())
}
}
}
return nil
}
// [END compute_instances_list_all]
However the problem is when I run my main function that calls ListAllInstances, it returns a <nil>. Not allowing me to know what is wrong.
caller api.go module where I run go run .:
package main
import (
"fmt"
"example.com/compute"
"bytes"
)
func main() {
buf := new(bytes.Buffer)
// Get a message and print it.
respone := compute.ListAllInstances(buf, "project-unique-id")
fmt.Println(respone)
}
How else can I further debug this to figure out what is wrong with my code?
You're not printing buf. Your function returns an object of type error, which is nil (no error!), the actual output is written to buf.
Either print it out:
func main() {
buf := new(bytes.Buffer)
// Get a message and print it.
err := compute.ListAllInstances(buf, "project-unique-id")
if err != nil {
panic(err)
}
fmt.Println(buf.String()) // <======= Print buf contents!
}
Or just use os.Stdout:
func main() {
err := compute.ListAllInstances(os.Stdout, "project-unique-id")
if err != nil {
panic(err)
}
}
To answer your question about debugging, try using VSCode with the Go extension, in there you can run a debugger, set breakpoints and step through the code line-by-line, watching how variables change.
See also Debug Go programs in VS Code.
I'm playing around with chromedp and been trying to replicate the functionality in puppeteer node.js but in golang.
I'm finding that the same JSON payload to chromium is causing an error when using chromedp
package main
import (
"context"
"io/ioutil"
"log"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
// create context
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// capture pdf
var buf []byte
if err := chromedp.Run(ctx, printToPDF(`<html><body><h1>Yeeeew!</h1></body></html>`, &buf)); err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile("sample.pdf", buf, 0644); err != nil {
log.Fatal(err)
}
}
// https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/PDFOptions.ts#L74
// https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/Page.ts#L3366
//https://github.com/chromedp/chromedp/issues/836
func printToPDF(html string, res *[]byte) chromedp.Tasks {
return chromedp.Tasks{
chromedp.Navigate("about:blank"),
chromedp.ActionFunc(func(ctx context.Context) error {
frameTree, err := page.GetFrameTree().Do(ctx)
if err != nil {
return err
}
return page.SetDocumentContent(frameTree.Frame.ID, html).Do(ctx)
}),
chromedp.ActionFunc(func(ctx context.Context) error {
buf, _, err := page.PrintToPDF().
// WithPrintBackground(false).
WithMarginTop(20.0).
// WithMarginLeft(20).
// WithMarginBottom(20.0).
// WithMarginRight(20).
Do(ctx)
if err != nil {
return err
}
*res = buf
return nil
}),
}
}
I've vendored the modules and edited cdproto/page/page.go to print out the JSON being sent to chromium
{"marginTop":20,"marginBottom":0,"marginLeft":0,"marginRight":0,"transferMode":"ReturnAsStream"}
I've also done this in node.js and logged out the json to compare
node index.js
PDF command: 'Page.printToPDF' {
transferMode: 'ReturnAsStream',
marginTop: 20,
marginBottom: 20,
marginLeft: 0,
marginRight: 0
}
I'm not sure why I'm getting this error? Any ideas?
TL;DR
The margin value is too big. I think you meant to pass 20.0/96 inches:
- WithMarginTop(20.0).
+ WithMarginTop(20.0/96).
Explanation
The error message returned from chromium is misleading. I guess here is what happened: the provided margin settings is invalid, and since chromium is running in headless mode, it can not show the error dialog. The error message can be interpreted as "I can not show a dialog to alert the user that the provided printer settings are invalid".
"marginTop":20 in the raw CDP message means 20 inches on the top, which is too big for an A4 page (A4: 8.27in x 11.7in). Please note that a number in puppeteer is treated as pixels and will be converted to inches before sending to chromium (see https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/Page.ts#L3366-L3402). So the fix is obvious.
BTW, there are easy ways to see the raw CDP messages:
chromedp: use the chromedp.WithDebugf option:
ctx, cancel = chromedp.NewContext(context.Background(), chromedp.WithDebugf(log.Printf))`
puppeteer: env DEBUG="puppeteer:*" node script.js. See https://github.com/puppeteer/puppeteer#debugging-tips
I have cloned the Stellar Horizon Repo from GitHub written in Go.
I thought to run the test cases first.where the test cases have been written by using GINKGO Testing Framework. I have been running the test cases using ginkgo command
eg : ginkgo (package path name will be given here).
This is how I run test cases. Test cases for particular package has been executing properly.
But I am getting a panic in the first test file only. Which I debugged and found that the panic is occurring while running a command. Please find the below details for reference .
File name : action_accounts_test.go
func name : TestAccountAction_Show() // Has been defined below
func TestAccountActions_Show(t *testing.T) {
ht := StartHTTPTest(t, "allow_trust") **// This function is not returning anything. Its //getting panic inside this //**
defer ht.Finish()
// existing account
w := ht.Get(
"/accounts/GCXKG6RN4ONIEPCMNFB732A436Z5PNDSRLGWK7GBLCMQLIFO4S7EYWVU",
)
if ht.Assert.Equal(200, w.Code) {
var result horizon.Account
err := json.Unmarshal(w.Body.Bytes(), &result)
ht.Require.NoError(err)
ht.Assert.Equal("8589934593", result.Sequence)
ht.Assert.NotEqual(0, result.LastModifiedLedger)
for _, balance := range result.Balances {
if balance.Type == "native" {
ht.Assert.Equal(uint32(0), balance.LastModifiedLedger)
} else {
ht.Assert.NotEqual(uint32(0), balance.LastModifiedLedger)
}
}
}
// missing account
w = ht.Get("/accounts/GDBAPLDCAEJV6LSEDFEAUDAVFYSNFRUYZ4X75YYJJMMX5KFVUOHX46SQ")
ht.Assert.Equal(404, w.Code)
}
I did a Debugging and found that its getting panic in the below func call which happens inside the above func StartHTTPTest()
scenarios.Load(StellarCoreDatabaseURL(), stellarCorePath)
scenarios.Load(DatabaseURL(), horizonPath)
Definition of the particular func
func Load(url string, path string) {
log.Println("database url", url, " Path : ", path)
sql, err := Asset(path)
log.Println("Print err:", err, " sql :", sql)
if err != nil {
log.Panic(err)
}
reader := bytes.NewReader(sql)
cmd := exec.Command("psql", url)
cmd.Stdin = reader
err = cmd.Run() **// Exactly here it return some error**
log.Println("Print err", err)
if err != nil { **// Since err is not nil .the statement will get executed .**
**log.Panic(err)**
}
}
The Error returned by cmd.Run() is exit status 2
I just printed the error and found this is the error exit status 2
What is the reason for the particular error?