Skip to content

Commit

Permalink
Create manifest file programmatically
Browse files Browse the repository at this point in the history
This removes the hassle for the user to mess with manifest files.

We also have control over the exact contents of the manifest file, no user errors.
  • Loading branch information
Lars committed Aug 20, 2018
1 parent 02935ba commit 9ec6100
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 42 deletions.
42 changes: 0 additions & 42 deletions README.mdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,6 @@ func main() {
}
```

##### Create Manifest `test.manifest`

```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
```

Then either compile the manifest using the [rsrc tool](https://github.com/akavel/rsrc), like this:

go get github.com/akavel/rsrc
rsrc -manifest test.manifest -o rsrc.syso

or rename the `test.manifest` file to `test.exe.manifest` and distribute it with the application instead.

##### Build app

In the directory containing `test.go` run
Expand All @@ -106,22 +80,6 @@ To get rid of the cmd window, instead run
##### More Examples
There are some [examples](examples) that should get you started.

Application Manifest Files
==========================
Walk requires Common Controls 6. This means that you must put an appropriate
application manifest file either next to your executable or embedded as a
resource.

You can copy one of the application manifest files that come with the examples.

To embed a manifest file as a resource, you can use the [rsrc tool](https://github.com/akavel/rsrc).

IMPORTANT: If you don't embed a manifest as a resource, then you should not launch
your executable before the manifest file is in place.
If you do anyway, the program will not run properly. And worse, Windows will not
recognize a manifest file, you later drop next to the executable. To fix this,
rebuild your executable and only launch it with a manifest file in place.

Program Crashes
===============
By default Go uses os threads with small stack sizes of 128KB. If your walk app crashes, it may be due
Expand Down
49 changes: 49 additions & 0 deletions manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package walk

import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"syscall"

"github.com/lxn/win"
)

/*
This function creates a manifest file for this application and activates it
before creating the GUI controls. This way, the common controls version 6 is
used automatically and the users of this library does not need to mess with
manifest files themselves.
*/
func init() {
appName := filepath.Base(os.Args[0])
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
manifest := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="` + appName + `" type="win32"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>`
// create a temporary manifest file, load it, then delete it
f, err := ioutil.TempFile("", "manifest_")
if err != nil {
return
}
manifestPath := f.Name()
defer os.Remove(manifestPath)
f.WriteString(manifest)
f.Close()
ctx := win.CreateActCtx(&win.ACTCTX{
Source: syscall.StringToUTF16Ptr(manifestPath),
})
win.ActivateActCtx(ctx)
}

0 comments on commit 9ec6100

Please sign in to comment.