Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit542ef81

Browse files
committed
Fix for fsbugs issue "can't run F# Console Application with 'update' in name".
Root cause was that compiler was not embedding a win32 manifest into generated executables, thus all EXEs were running virtualized and at the mercy of "Installer Detection Technology" (seehttp://technet.microsoft.com/en-us/library/cc709628(v=WS.10).aspx for heuristics used). EXEs with "update", "install", etc in their file names triggered the heuristic and required admin privs to run. Trying to start these from VS would not work unless you were also running VS as admin. The old logic used to decide whether to embed a manifest was tied to .NET version and had drifted out of date.New logic is to embed the default manifest for all EXEs unless there is some specific config that precludes this. New test added to validate that a manifest is present for EXE, absent for DLL. (changeset 1232952)
1 parentd8ee80f commit542ef81

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

‎src/fsharp/fsc.fs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,15 +1255,15 @@ module MainModuleBuilder =
12551255
error(Error(FSComp.SR.fscTwoResourceManifests(),rangeCmdArgs));
12561256

12571257
letwin32Manifest=
1258+
// use custom manifest if provided
12581259
ifnot(tcConfig.win32manifest="")then
12591260
tcConfig.win32manifest
1260-
elifnot(tcConfig.includewin32manifest)||not(tcConfig.win32res="")|| runningOnMonothen// don't embed a manifest if a native resource is being included
1261+
// don't embed a manifest if target is not an exe, if manifest is specifically excluded, if another native resource is being included, or if running on mono
1262+
elifnot(tcConfig.target.IsExe)||not(tcConfig.includewin32manifest)||not(tcConfig.win32res="")|| runningOnMonothen
12611263
""
1264+
// otherwise, include the default manifest
12621265
else
1263-
match MSBuildResolver.HighestInstalledNetFrameworkVersionMajorMinor()with
1264-
|_,"v4.0"-> System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()+@"default.win32manifest"
1265-
|_,"v3.5"-> System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()+@"..\v3.5\default.win32manifest"
1266-
|_,_->""// only have default manifests for 3.5 and 4.0
1266+
System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()+@"default.win32manifest"
12671267

12681268
letnativeResources=
12691269
[for avin assemblyVersionResourcesdo
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// The compiler should add an embedded default win32 manifest so that UAC is handled properly
2+
// <Expects status=success></Expects>
3+
4+
openSystem
5+
openSystem.Text
6+
openSystem.Reflection
7+
openSystem.Runtime.InteropServices
8+
openMicrosoft.FSharp.NativeInterop
9+
openFSharp.Test.DefaultManifest
10+
11+
moduleNativeMethods=
12+
typeEnumResourceNamesCallback=delegateofIntPtr*IntPtr*IntPtr*IntPtr->bool
13+
14+
[<DllImport("kernel32.dll")>]
15+
extern IntPtr LoadLibrary(char[] lpFileName)
16+
17+
[<DllImport("kernel32.dll")>]
18+
extern bool EnumResourceNames(IntPtr hModule, int dwID, EnumResourceNamesCallback lpEnumFunc, IntPtr lParam)
19+
20+
[<DllImport("kernel32.dll")>]
21+
extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType)
22+
23+
[<DllImport("kernel32.dll")>]
24+
extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo)
25+
26+
[<DllImport("kernel32.dll")>]
27+
extern uint32 SizeofResource(IntPtr hModule, IntPtr hResInfo)
28+
29+
[<DllImport("kernel32.dll")>]
30+
extern IntPtr LockResource(IntPtr hResData)
31+
32+
// ID of the manifest win32 resource type
33+
letRT_MANIFEST=24
34+
35+
/// extracts the win32 manifest of the specified assembly
36+
letgetManifest(path:string)=
37+
letmanifest:string option ref= ref None
38+
letcallback=
39+
NativeMethods.EnumResourceNamesCallback(fun(hModule:IntPtr)(lpszType:IntPtr)(lpszName:IntPtr)(lParam:IntPtr)->
40+
letresourceAsString=
41+
lethResInfo= NativeMethods.FindResource(hModule, lpszName, lpszType)
42+
lethResData= NativeMethods.LoadResource(hModule, hResInfo)
43+
letresSize= NativeMethods.SizeofResource(hModule, hResInfo)|> int
44+
lethResMem= NativeMethods.LockResource(hResData)
45+
46+
letbuff= Array.zeroCreate<byte> resSize
47+
Marshal.Copy(hResMem, buff,0, resSize)
48+
String(buff|> Array.map char)
49+
50+
manifest:= Some(resourceAsString)
51+
true
52+
)
53+
54+
lethLib= NativeMethods.LoadLibrary(path.ToCharArray())
55+
NativeMethods.EnumResourceNames(hLib, NativeMethods.RT_MANIFEST, callback, IntPtr.Zero)|> ignore
56+
!manifest
57+
58+
letexePath= System.Reflection.Assembly.GetExecutingAssembly().Location
59+
letdllPath=(TestType()).GetType().Assembly.Location
60+
61+
letmanifests=[exePath; dllPath]|> List.map getManifest
62+
63+
match manifestswith
64+
|[Some(m); None]->
65+
printfn"Found exe manifest and no DLL manifest. This is expected."
66+
printfn"Exe manifest content:%s" m
67+
if m.Contains("requestedExecutionLevel")then exit0
68+
else
69+
printfn"Exe manifest does not contain expected content"
70+
exit1
71+
|[exeM; dllM]->
72+
printfn"Unexpected manifest result."
73+
printfn"EXE manifest:%A" exeM
74+
printfn"DLL manifest:%A" dllM
75+
exit1
76+
|_-> exit1// should never get here
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespaceFSharp.Test.DefaultManifest
2+
3+
typeTestType()=classend

‎tests/fsharpqa/Source/Misc/env.lst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
# Apparently, 'GetManifestResourceInfo' does not exist on Mono -> disabling
2020
NOMONOSOURCE=WhetherEmbededManifest.fs# WhetherEmbededManifest.fs
21+
PRECMD="\$FSC_PIPE -a DefaultManifest_dll.fs" SCFLAGS="-r:DefaultManifest_dll.dll" SOURCE=DefaultManifest.fs# DefaultManifest.fs
2122

2223
SOURCE=UserCodeSnippet01.fs SCFLAGS=-a# UserCodeSnippet01.fs
2324

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp