gpt4 book ai didi

c# - Visual Studio - 以编程方式获取启动项目

转载 作者:太空宇宙 更新时间:2023-11-03 23:14:45 25 4
gpt4 key购买 nike

我正在构建一个 .Net 应用程序,它应该导入 VS2010/2008 解决方案并通过读取 .suo 文件找到启动项目。我看了How do I programmatically find out the Action of each StartUp Project in a solution?但仅当我在“解决方案属性”窗口中选择“多个启动项目”时,提到的解决方案才有效。我的解决方案没有多个启动项目。当解决方案只有1个启动项目时,有没有办法找到启动项目?

这是代码

public static class StartUpProjectHelper
{

public static FileInfo GetStartUpProject(FileInfo solutionFile)
{
FileInfo startUpProject = null;

string suoFile = solutionFile.FullName.Substring(0, solutionFile.FullName.Length - 4) + ".suo";

string guid = null;

bool found = false;

foreach (var kvp in ReadStartupOptions(suoFile))
{
if (((kvp.Value & 1) != 0 || (kvp.Value & 2) != 0) && !found)
{
guid = kvp.Key.ToString();

found = true;
}
}

if (!string.IsNullOrEmpty(guid))
{
string projectname = GetProjectNameFromGuid(solutionFile, guid).Trim().TrimStart('\"').TrimEnd('\"');

startUpProject = new FileInfo(Path.Combine(solutionFile.DirectoryName, projectname));
}

return startUpProject;
}


public static string GetProjectNameFromGuid(FileInfo solutionFile, string guid)
{
string projectName = null;

using (var reader = new StreamReader(solutionFile.FullName))
{
string line;

bool found = false;

while ((line = reader.ReadLine()) != null && !found)
{
// sample format
//Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Saltus.digiTICKET.laptop", "digiTICKET.laptop\Saltus.digiTICKET.laptop.csproj",
//"{236D51A1-DEB7-41C3-A4C1-1D16D0A85382}" EndProject

if ((line.IndexOf(guid.ToUpper()) > -1) && line.Contains(",") && line.Contains("="))
{
projectName = line.Split(',')[1].Split(',')[0];

found = true;
}
}
}

return projectName;
}

//// from https://stackoverflow.com/questions/8817693/how-do-i-programmatically-find-out-the-action-of-each-startup-project-in-a-solut
public static IDictionary<Guid, int> ReadStartupOptions(string filePath)
{
if (filePath == null)
{
throw new InvalidOperationException("No file selected");
}


// look for this token in the file
const string token = "dwStartupOpt\0=";

byte[] tokenBytes = Encoding.Unicode.GetBytes(token);

var dic = new Dictionary<Guid, int>();

byte[] bytes;

using (var stream = new MemoryStream())
{
ExtractStream(filePath, "SolutionConfiguration", stream);

bytes = stream.ToArray();
}

int i = 0;
do
{
bool found = true;
for (int j = 0; j < tokenBytes.Length; j++)
{
if (bytes[i + j] != tokenBytes[j])
{
found = false;
break;
}
}
if (found)
{
// back read the corresponding project guid
// guid is formatted as {guid}
// len to read is Guid length* 2 and there are two offset bytes between guid and startup options token
var guidBytes = new byte[38*2];
Array.Copy(bytes, i - guidBytes.Length - 2, guidBytes, 0, guidBytes.Length);
var guid = new Guid(Encoding.Unicode.GetString(guidBytes));

// skip VT_I4
int options = BitConverter.ToInt32(bytes, i + tokenBytes.Length + 2);
dic[guid] = options;
}
i++;
} while (i < bytes.Length);
return dic;
}

public static void ExtractStream(string filePath, string streamName, Stream output)
{
if (filePath == null)
throw new ArgumentNullException("filePath");

if (streamName == null)
throw new ArgumentNullException("streamName");

if (output == null)
throw new ArgumentNullException("output");

IStorage storage;
int hr = StgOpenStorage(filePath, null, STGM.READ | STGM.SHARE_DENY_WRITE, IntPtr.Zero, 0, out storage);
if (hr != 0)
throw new Win32Exception(hr);

try
{
IStream stream;
hr = storage.OpenStream(streamName, IntPtr.Zero, STGM.READ | STGM.SHARE_EXCLUSIVE, 0, out stream);
if (hr != 0)
throw new Win32Exception(hr);

int read = 0;
IntPtr readPtr = Marshal.AllocHGlobal(Marshal.SizeOf(read));
try
{
var bytes = new byte[0x1000];
do
{
stream.Read(bytes, bytes.Length, readPtr);
read = Marshal.ReadInt32(readPtr);
if (read == 0)
break;

output.Write(bytes, 0, read);
} while (true);
}
finally
{
Marshal.FreeHGlobal(readPtr);
Marshal.ReleaseComObject(stream);
}
}
finally
{
Marshal.ReleaseComObject(storage);
}
}

[DllImport("ole32.dll")]
private static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved,
out IStorage ppstgOpen);

#region Nested type: IStorage

[ComImport, Guid("0000000b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IStorage
{
void Unimplemented0();

[PreserveSig]
int OpenStream([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IntPtr reserved1, STGM grfMode,
uint reserved2, out IStream ppstm);

// other methods not declared for simplicity
}

#endregion

#region Nested type: STGM

[Flags]
private enum STGM
{
READ = 0x00000000,
SHARE_DENY_WRITE = 0x00000020,
SHARE_EXCLUSIVE = 0x00000010,
// other values not declared for simplicity
}

#endregion
}

//// from https://stackoverflow.com/questions/8817693/how-do-i-programmatically-find-out-the-action-of-each-startup-project-in-a-solut``

最佳答案

这是解决方案。它主要基于 @SimonMourier post ,但我没有搜索“dwStartupOpt\0=”,而是在寻找“StartupProject\0=&\0”。此标记仅在 .suo 文件中出现一次,后跟启动项目的 GUID。

public static FileInfo GetStartUpProject(FileInfo solutionFile)
{
FileInfo startUpProject = null;

string projectName = Path.GetFileNameWithoutExtension(solutionFile.FullName);

FileInfo suoFileInfo = new FileInfo(Path.Combine(solutionFile.Directory.FullName, string.Format(projectName + "{0}", ".suo")));

string guid = ReadStartupOptions(suoFileInfo.FullName).ToString();

if (!string.IsNullOrEmpty(guid))
{
string projectname = GetProjectNameFromGuid(solutionFile, guid).Trim().TrimStart('\"').TrimEnd('\"');

startUpProject = new FileInfo(Path.Combine(solutionFile.DirectoryName, projectname));
}

return startUpProject;
}


public static string GetProjectNameFromGuid(FileInfo solutionFile, string guid)
{
string projectName = null;

using (var reader = new StreamReader(solutionFile.FullName))
{
string line;

bool found = false;

while ((line = reader.ReadLine()) != null && !found)
{


if ((line.IndexOf(guid.ToUpper()) > -1) && line.Contains(",") && line.Contains("="))
{
projectName = line.Split(',')[1].Split(',')[0];

found = true;
}
}
}

return projectName;
}

// from https://stackoverflow.com/questions/8817693/how-do-i-programmatically-find-out-the-action-of-each-startup-project-in-a-solut
public static Guid ReadStartupOptions(string filePath)
{
Guid guid = new Guid();

if (filePath == null)
{
throw new InvalidOperationException("No file selected");
}

const string token = "StartupProject\0=&\0";

byte[] tokenBytes = Encoding.Unicode.GetBytes(token);

byte[] bytes;

using (var stream = new MemoryStream())
{
ExtractStream(filePath, "SolutionConfiguration", stream);

bytes = stream.ToArray();
}

var guidBytes = new byte[36 * 2];

for (int i2 = 0; i2 < bytes.Length; i2++)
{
if (bytes.Skip(i2).Take(tokenBytes.Length).SequenceEqual(tokenBytes))
{
Array.Copy(bytes, i2 + tokenBytes.Length + 2, guidBytes, 0, guidBytes.Length);

guid = new Guid(Encoding.Unicode.GetString(guidBytes));

break;
}
}

return guid;

}

public static void ExtractStream(string filePath, string streamName, Stream output)
{
if (filePath == null)
throw new ArgumentNullException("filePath");

if (streamName == null)
throw new ArgumentNullException("streamName");

if (output == null)
throw new ArgumentNullException("output");

IStorage storage;
int hr = StgOpenStorage(filePath, null, STGM.READ | STGM.SHARE_DENY_WRITE, IntPtr.Zero, 0, out storage);
if (hr != 0)
throw new Win32Exception(hr);

try
{
IStream stream;
hr = storage.OpenStream(streamName, IntPtr.Zero, STGM.READ | STGM.SHARE_EXCLUSIVE, 0, out stream);
if (hr != 0)
throw new Win32Exception(hr);

int read = 0;
IntPtr readPtr = Marshal.AllocHGlobal(Marshal.SizeOf(read));
try
{
var bytes = new byte[0x1000];
do
{
stream.Read(bytes, bytes.Length, readPtr);
read = Marshal.ReadInt32(readPtr);
if (read == 0)
break;

output.Write(bytes, 0, read);
} while (true);
}
finally
{
Marshal.FreeHGlobal(readPtr);
Marshal.ReleaseComObject(stream);
}
}
finally
{
Marshal.ReleaseComObject(storage);
}
}

[DllImport("ole32.dll")]
private static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved,
out IStorage ppstgOpen);

#region Nested type: IStorage

[ComImport, Guid("0000000b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IStorage
{
void Unimplemented0();

[PreserveSig]
int OpenStream([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IntPtr reserved1, STGM grfMode,
uint reserved2, out IStream ppstm);

// other methods not declared for simplicity
}

#endregion

#region Nested type: STGM

[Flags]
private enum STGM
{
READ = 0x00000000,
SHARE_DENY_WRITE = 0x00000020,
SHARE_EXCLUSIVE = 0x00000010,
// other values not declared for simplicity
}

#endregion

关于c# - Visual Studio - 以编程方式获取启动项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37618573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com