WPF 形式的 C++/CLI XML 创建方法 Dll
更新:我已根据评论修改了帖子。
这将是一篇稍长的文章,对此我表示歉意,但我希望人们在删除它之前了解我想要做什么。我之前问过一些关于在 C++/CLI 中创建 XML 的方法的问题,我想继续使用它们。
最近我开始测试 C# 和 WPF,我真的很享受它为视觉效果提供的创造力和自由度。我开始将当前正在处理的应用程序的功能转换为 DLL,这样我就不必重做我已经完成的工作,并且因为我想学习并获得一些编写 DLL 和使用互操作的经验。
到目前为止,每个函数都只有一个输入或输出。然而,我的最后两个函数(它获取文件名列表和文件本身的哈希值,并为每个文件和哈希值将其保存到 xml 文件)对我来说效果不太好。我得到输出,但不是我想要的形式,所以显然我的逻辑有缺陷,但我不知道如何纠正它。
这些功能非常相似,唯一的区别是第一个创建一个全新的 xml,而第二个更新现有的 xml。它们之前都作为直接的 C++/CLI 函数完美工作,但是现在我需要在 C# 中使用它们,我必须将它们放入迭代中,以便它们适用于列表中显示的每个文件及其哈希值。
下面是 Dll 中的函数之一,我现在已将以前的硬编码变量替换为 listBox2->Items[x]->ToString() 作为变量,例如 CurrentFile,现在在 . CS。
public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName,
String^ ProjectTC, String^ CurrentFile, String^ CurrentHash)
{
try
{
XmlDocument^ XmlDoc = gcnew XmlDocument();
XmlDoc->Load(Location);
XmlElement^ NewProject = XmlDoc->CreateElement("Project");
NewProject->SetAttribute("Name", ProjectName);
XmlDoc->DocumentElement->AppendChild(NewProject);
XmlElement^ NewTestCycle = XmlDoc->CreateElement("TestCycle");
NewTestCycle->SetAttribute("Number", ProjectTC);
NewProject->AppendChild(NewTestCycle);
XmlElement^ NewFile = XmlDoc->CreateElement("Files");
NewTestCycle->AppendChild(NewFile);
for (int x = 0; x < NumberItems; ++x)
{
String^ FileName = CurrentFile;
String^ Hash = CurrentHash;
XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
NewFileName->SetAttribute("File", FileName);
NewFile->AppendChild(NewFileName);
XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
NewHashCode->SetAttribute("Code", Hash);
NewFile->AppendChild(NewHashCode);
}
XmlDoc->Save(Location);
return;
}
catch(Exception^)
{
return;
}
}
以下是我的 WPF 表单中对 dll 的方法的调用:
private void button2_Click(object sender, RoutedEventArgs e)
{
DllTest.Funtions Functions = new DllTest.Funtions();
String Name = textBox1.Text;
String TC = textBox2.Text;
String Location = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
int Number = listBox2.Items.Count;
for (int x = 0; x < listBox2.Items.Count; ++x)
{
Functions.XMLUpdate(Location, Number, TC, Name, listBox2.Items[x].ToString(),
listBox3.Items[x].ToString());
}
}
输出仅获取列表中的最后一项,并按列表中的编号复制它,在本例中,列表有 3 个文件名,第二个列表有 3 个哈希值是一个例子:
<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
<TestCycle Number="1">
<Files>
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
</Project>
所以这是第二个函数,它更新现有的 XML,并提供与新函数中的输出完全不同的输出,但仍然不正确。
public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName,
String^ ProjectTC, String^ CurrentFile, String^ CurrentHash)
{
try
{
XmlDocument^ XmlDoc = gcnew XmlDocument();
XmlDoc->Load(Location);
XmlElement^ NewProject = XmlDoc->CreateElement("Project");
NewProject->SetAttribute("Name", ProjectName);
XmlDoc->DocumentElement->AppendChild(NewProject);
XmlElement^ NewTestCycle = XmlDoc->CreateElement("TestCycle");
NewTestCycle->SetAttribute("Number", ProjectTC);
NewProject->AppendChild(NewTestCycle);
XmlElement^ NewFile = XmlDoc->CreateElement("Files");
NewTestCycle->AppendChild(NewFile);
for (int x = 0; x < NumberItems; ++x)
{
String^ FileName = CurrentFile;
String^ Hash = CurrentHash;
XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
NewFileName->SetAttribute("File", FileName);
NewFile->AppendChild(NewFileName);
XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
NewHashCode->SetAttribute("Code", Hash);
NewFile->AppendChild(NewHashCode);
}
XmlDoc->Save(Location);
return;
}
catch(Exception^)
{
return;
}
}
方法调用:
private void button4_Click(object sender, RoutedEventArgs e)
{
DllTest.Funtions Functions = new DllTest.Funtions();
String Name = textBox1.Text;
String TC = textBox2.Text;
String path = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
int Number = listBox2.Items.Count;
for (int x = 0; x < listBox2.Items.Count; ++x)
{
Functions.XMLNew(path, Name, TC, Number, listBox2.Items[x].ToString(),
listBox3.Items[x].ToString());
}
}
这个的输出更接近我需要的,因为它使用列表中的所有项目,但它在每个元素中复制它们,我只想要一个带有新文件及其哈希值的新元素。
<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
<TestCycle Number="1">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
</Project>
所以现在您可以看到问题,我在循环中存在循环,导致输出重复自身。如果您需要,我可以发布我的输出示例。
但对于我的一生来说,我无法绕过它,我尝试将功能分成几个部分,但尝试这样做时遇到错误。
有人能找到解决这个问题的方法吗?如果这是我唯一的选择,我只想完全重写 C# 中的方法,因为我想要 dll 中的所有主要函数。请不要因为我缺乏知识而批评我,我仍然是第一次学习和测试很多东西。
谢谢
Update: I have modified the post as per comments.
This is going to be a slightly long post i apologize for that, but i want people to understand what im trying to do before shooting it down. I've asked a few question previously about creating methods to create XMLs in C++/CLI and I want to continue using them.
Recently i started testing out C# and WPF and im really enjoying the creativity and freedom it offers for visual effects. I started converting the functions of an application i am currently working on into a DLL mostly so i don't have to redo the work I have already done and because i want to learn and gain some experience in writing DLL's and using interop.
Every function so far has only had a single input or output. However my final two functions (Which take a list of filenames and the hash of the file its self and for each file and hash saves it to an xml file) aren't working so well for me. Im getting output but not in the form i want it so obviously my logic is flawed but im not sure how to correct it.
The functions are very similar the only difference is the one creates a brand new xml while the second updates an existing xml. They both worked perfectly before as straight C++/CLI functions however now that i need to use them in C# i have to put them in iterations so they work for each of the files and their hashes displayed in the lists.
Below is one of the functions in the Dll where i have now replaced the previous hard-coded variables which would have been listBox2->Items[x]->ToString() as varibales such as CurrentFile which are now defined in the .cs.
public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName,
String^ ProjectTC, String^ CurrentFile, String^ CurrentHash)
{
try
{
XmlDocument^ XmlDoc = gcnew XmlDocument();
XmlDoc->Load(Location);
XmlElement^ NewProject = XmlDoc->CreateElement("Project");
NewProject->SetAttribute("Name", ProjectName);
XmlDoc->DocumentElement->AppendChild(NewProject);
XmlElement^ NewTestCycle = XmlDoc->CreateElement("TestCycle");
NewTestCycle->SetAttribute("Number", ProjectTC);
NewProject->AppendChild(NewTestCycle);
XmlElement^ NewFile = XmlDoc->CreateElement("Files");
NewTestCycle->AppendChild(NewFile);
for (int x = 0; x < NumberItems; ++x)
{
String^ FileName = CurrentFile;
String^ Hash = CurrentHash;
XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
NewFileName->SetAttribute("File", FileName);
NewFile->AppendChild(NewFileName);
XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
NewHashCode->SetAttribute("Code", Hash);
NewFile->AppendChild(NewHashCode);
}
XmlDoc->Save(Location);
return;
}
catch(Exception^)
{
return;
}
}
Here is the call for the method from the dll in my WPF form:
private void button2_Click(object sender, RoutedEventArgs e)
{
DllTest.Funtions Functions = new DllTest.Funtions();
String Name = textBox1.Text;
String TC = textBox2.Text;
String Location = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
int Number = listBox2.Items.Count;
for (int x = 0; x < listBox2.Items.Count; ++x)
{
Functions.XMLUpdate(Location, Number, TC, Name, listBox2.Items[x].ToString(),
listBox3.Items[x].ToString());
}
}
Output is only taking the last item in the list and duplicating it by the number in the list in this case the list had 3 filenames and the second list had 3 hashes here is an example:
<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
<TestCycle Number="1">
<Files>
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName
File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode
Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
</Project>
So here is the second function that updates an exisitng XML and gives me completely different output, still incorrect, from the output in the new function.
public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName,
String^ ProjectTC, String^ CurrentFile, String^ CurrentHash)
{
try
{
XmlDocument^ XmlDoc = gcnew XmlDocument();
XmlDoc->Load(Location);
XmlElement^ NewProject = XmlDoc->CreateElement("Project");
NewProject->SetAttribute("Name", ProjectName);
XmlDoc->DocumentElement->AppendChild(NewProject);
XmlElement^ NewTestCycle = XmlDoc->CreateElement("TestCycle");
NewTestCycle->SetAttribute("Number", ProjectTC);
NewProject->AppendChild(NewTestCycle);
XmlElement^ NewFile = XmlDoc->CreateElement("Files");
NewTestCycle->AppendChild(NewFile);
for (int x = 0; x < NumberItems; ++x)
{
String^ FileName = CurrentFile;
String^ Hash = CurrentHash;
XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
NewFileName->SetAttribute("File", FileName);
NewFile->AppendChild(NewFileName);
XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
NewHashCode->SetAttribute("Code", Hash);
NewFile->AppendChild(NewHashCode);
}
XmlDoc->Save(Location);
return;
}
catch(Exception^)
{
return;
}
}
The method call:
private void button4_Click(object sender, RoutedEventArgs e)
{
DllTest.Funtions Functions = new DllTest.Funtions();
String Name = textBox1.Text;
String TC = textBox2.Text;
String path = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
int Number = listBox2.Items.Count;
for (int x = 0; x < listBox2.Items.Count; ++x)
{
Functions.XMLNew(path, Name, TC, Number, listBox2.Items[x].ToString(),
listBox3.Items[x].ToString());
}
}
the output for this one which is closer to what i need since it using all of the items in the list but its duplicating them in every element i only want a single new element with the new files and their hashes.
<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
<TestCycle Number="1">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
<HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
<HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
</Files>
</TestCycle>
</Project>
<Project Name="2">
<TestCycle Number="New">
<Files>
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
<FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
<HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
</Files>
</TestCycle>
</Project>
</Project>
So now you can see the problem i have loops within loops causing output that repeats its self. I can post an example of my output if you need.
But for the life of me i cannot get around it, i have tried splitting up the functions in to parts but i get errors trying to do that.
Can anyone see a way around this? I only want to completely rewrite the methods in c# if its my only alternative since i want all the main functions in the dll. Please dont bash me for my lack of knowledge im still learning and testing alot of things for the first time.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论