- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个我的世界模组,它是 Java 代码,我注意到一个奇怪的行为,其中一个字符串似乎正在丢失它的数据。我是 Java 新手,所以我不太了解 Java 如何处理字符串或其他对象。因此,我将说明我正在做什么以及问题出在哪里:我有一个类,其中有一些文本字段 ui 元素,用户可以输入这些元素来为项目命名。然后我要做的是每次用户更改字段中的文本时,它都会将其内容的副本发送到另一个类,然后将它们发送到另一个类(由于我的世界的设置方式,这是必要的),然后当该项目是创建后,最后一个类就会从其自身内部更新该项目的名称。我不确定这是否是最好的方法,但这是我在短期内想到的。问题是,当创建项目时,最后一个类的名称字段(字符串)被删除并为空。我不确定为什么会发生这种情况或如何发生,因为每个名称字段仅在 ui 中的文本更改时才会(重新)定义,并且对于各自的类来说是私有(private)的。所以,我很茫然。我将发布我的类(class),希望你们能够理解它们并帮助我。
GuiRecorder.java
package net.minecraft.src;
import org.lwjgl.opengl.GL11;
public class GuiRecorder extends GuiContainer
{
private TileEntityRecorder recorderInventory;
private GuiTextField discName;
private GuiTextField musicPath;
private ContainerRecorder record;
private boolean isInit;
public GuiRecorder(InventoryPlayer par1InventoryPlayer, TileEntityRecorder par2TileEntityRecorder)
{
super(new ContainerRecorder(par1InventoryPlayer, par2TileEntityRecorder));
this.recorderInventory = par2TileEntityRecorder;
this.record = (ContainerRecorder)(this.inventorySlots);
int var5 = (this.width - this.xSize) / 2;
int var6 = (this.height - this.ySize) / 2;
this.isInit = false;
}
/**
* Capture Any/All key presses from the user and put them in the correct text field.
*/
protected void keyTyped(char par1, int par2)
{
if (par2 == 1)
{
this.mc.thePlayer.closeScreen();
}
else if (this.discName.isFocused())
{
this.discName.textboxKeyTyped(par1, par2);
}
else if (this.musicPath.isFocused())
{
this.musicPath.textboxKeyTyped(par1, par2);
}
System.out.println("Keyboard hit! Code: " + par2);
this.record.setName(this.discName.getText());
this.record.setPath(this.musicPath.getText());
}
/**
* Capture Any/All mouse clicks on the GUI.
*/
protected void mouseClicked(int par1, int par2, int par3)
{
super.mouseClicked(par1, par2, par3);
this.musicPath.mouseClicked(par1, par2, par3);
this.discName.mouseClicked(par1, par2, par3);
}
public void onGuiClosed()
{
this.record.setName(this.discName.getText());
this.record.setPath(this.musicPath.getText());
if (this.mc.thePlayer != null)
{
this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
}
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int par1, int par2)
{
this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
this.fontRenderer.drawString("Disc Name:", (int)(this.xSize*0.02), (int)(this.ySize*0.03)+1, 4210752);
this.fontRenderer.drawString("Music Path:", (int)(this.xSize*0.02), (int)(this.ySize*0.2)-1, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
{
int var4 = this.mc.renderEngine.getTexture("/gui/recorder.png");
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.renderEngine.bindTexture(var4);
int var5 = (this.width - this.xSize) / 2;
int var6 = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(var5, var6, 0, 0, this.xSize, this.ySize);
int var7;
if(!this.isInit)
{
this.discName = new GuiTextField(this.fontRenderer, var5 + 7, var6 + 16, 68, 10);
this.musicPath = new GuiTextField(this.fontRenderer, var5 + 7, var6 + 39, 68, 10);
this.discName.setFocused(true);
this.musicPath.setFocused(false);
this.discName.setText("Untitled");
this.musicPath.setText("cat");
this.isInit = true;
}
var7 = this.recorderInventory.getCookProgressScaled(24);
this.drawTexturedModalRect(var5 + 111, var6 + 34, 176, 14, var7 + 1, 16);
this.discName.drawTextBox();
this.musicPath.drawTextBox();
}
}
ContainerRecorder.java
package net.minecraft.src;
import java.util.Iterator;
public class ContainerRecorder extends Container
{
private TileEntityRecorder recorder;
private int lastCookTime = 0;
private int lastBurnTime = 0;
private int lastItemBurnTime = 0;
public volatile String name;
public volatile String path;
public ContainerRecorder(InventoryPlayer par1InventoryPlayer, TileEntityRecorder par2TileEntityRecorder)
{
this.recorder = par2TileEntityRecorder;
this.addSlotToContainer(new Slot(par2TileEntityRecorder, 0, 87, 35));
this.addSlotToContainer(new SlotRecorder(par1InventoryPlayer.player, par2TileEntityRecorder, 2, 148, 36));
int var3;
for (var3 = 0; var3 < 3; ++var3)
{
for (int var4 = 0; var4 < 9; ++var4)
{
this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18));
}
}
for (var3 = 0; var3 < 9; ++var3)
{
this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142));
}
this.name = "Untitled";
this.path = "cat";
}
public void addCraftingToCrafters(ICrafting par1ICrafting)
{
super.addCraftingToCrafters(par1ICrafting);
par1ICrafting.updateCraftingInventoryInfo(this, 0, this.recorder.currentBurnTime);
par1ICrafting.updateCraftingInventoryInfo(this, 2, this.recorder.currentItemBurnTime);
}
/**
* Updates crafting matrix; called from onCraftMatrixChanged. Args: none
*/
public void updateCraftingResults()
{
super.updateCraftingResults();
Iterator var1 = this.crafters.iterator();
while (var1.hasNext())
{
ICrafting var2 = (ICrafting)var1.next();
if (this.lastCookTime != this.recorder.currentBurnTime)
{
var2.updateCraftingInventoryInfo(this, 0, this.recorder.currentBurnTime);
}
if (this.lastItemBurnTime != this.recorder.currentItemBurnTime)
{
var2.updateCraftingInventoryInfo(this, 2, this.recorder.currentItemBurnTime);
}
}
this.lastCookTime = this.recorder.currentBurnTime;
this.lastBurnTime = this.recorder.burnTime;
this.lastItemBurnTime = this.recorder.currentItemBurnTime;
}
public void updateProgressBar(int par1, int par2)
{
if (par1 == 0)
{
this.recorder.currentBurnTime = par2;
}
if (par1 == 1)
{
this.recorder.burnTime = par2;
}
if (par1 == 2)
{
this.recorder.currentItemBurnTime = par2;
}
}
public boolean canInteractWith(EntityPlayer par1EntityPlayer)
{
return this.recorder.isUseableByPlayer(par1EntityPlayer);
}
public ItemStack func_82846_b(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack var3 = null;
Slot var4 = (Slot)this.inventorySlots.get(par2);
if (var4 != null && var4.getHasStack())
{
ItemStack var5 = var4.getStack();
var3 = var5.copy();
if (par2 == 2)
{
if (!this.mergeItemStack(var5, 3, 39, true))
{
return null;
}
var4.onSlotChange(var5, var3);
}
else if (par2 != 1 && par2 != 0)
{
if (RecorderRecipes.smelting().getSmeltingResult(var5.getItem().shiftedIndex) != null)
{
if (!this.mergeItemStack(var5, 0, 1, false))
{
return null;
}
}
else if (TileEntityRecorder.isItemFuel(var5))
{
if (!this.mergeItemStack(var5, 1, 2, false))
{
return null;
}
}
else if (par2 >= 3 && par2 < 30)
{
if (!this.mergeItemStack(var5, 30, 39, false))
{
return null;
}
}
else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(var5, 3, 30, false))
{
return null;
}
}
else if (!this.mergeItemStack(var5, 3, 39, false))
{
return null;
}
if (var5.stackSize == 0)
{
var4.putStack((ItemStack)null);
}
else
{
var4.onSlotChanged();
}
if (var5.stackSize == var3.stackSize)
{
return null;
}
var4.func_82870_a(par1EntityPlayer, var5);
}
return var3;
}
public void setName(final String aName)
{
this.name = aName;
System.out.println("<ContainerRecorder>Record Name Set! Name: " + this.name);
this.recorder.setDiscName(this.name);
this.recorder.setMusicPath(this.path);
}
public void setPath(final String aPath)
{
this.path = aPath;
System.out.println("<ContainerRecorder>Record Path Set! Path: " + this.path);
this.recorder.setDiscName(this.name);
this.recorder.setMusicPath(this.path);
}
}
TileEntityRecorderer.java
package net.minecraft.src;
public class TileEntityRecorder extends TileEntity implements IInventory
{
/**
* The ItemStacks that hold the items currently being used in the recorder
*/
private ItemStack[] recorderItemStacks = new ItemStack[3];
/** The number of ticks that the recorder will keep burning */
public int burnTime = 0;
/**
* The number of ticks that a fresh copy of the currently-burning item would keep the recorder burning for
*/
public int currentItemBurnTime = 0;
/** The number of ticks that the current item has been cooking for */
public int currentBurnTime = 0;
protected String name;
protected String path;
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.recorderItemStacks.length;
}
/**
* Returns the stack in slot i
*/
public ItemStack getStackInSlot(int par1)
{
return this.recorderItemStacks[par1];
}
/**
* Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
* new stack.
*/
public ItemStack decrStackSize(int par1, int par2)
{
if (this.recorderItemStacks[par1] != null)
{
ItemStack var3;
if (this.recorderItemStacks[par1].stackSize <= par2)
{
var3 = this.recorderItemStacks[par1];
this.recorderItemStacks[par1] = null;
return var3;
}
else
{
var3 = this.recorderItemStacks[par1].splitStack(par2);
if (this.recorderItemStacks[par1].stackSize == 0)
{
this.recorderItemStacks[par1] = null;
}
return var3;
}
}
else
{
return null;
}
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
public ItemStack getStackInSlotOnClosing(int par1)
{
if (this.recorderItemStacks[par1] != null)
{
ItemStack var2 = this.recorderItemStacks[par1];
this.recorderItemStacks[par1] = null;
return var2;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
{
this.recorderItemStacks[par1] = par2ItemStack;
if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
{
par2ItemStack.stackSize = this.getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory.
*/
public String getInvName()
{
return "container.recorder";
}
/**
* Reads a tile entity from NBT.
*/
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
NBTTagList var2 = par1NBTTagCompound.getTagList("Items");
this.recorderItemStacks = new ItemStack[this.getSizeInventory()];
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
byte var5 = var4.getByte("Slot");
if (var5 >= 0 && var5 < this.recorderItemStacks.length)
{
this.recorderItemStacks[var5] = ItemStack.loadItemStackFromNBT(var4);
}
}
this.name = par1NBTTagCompound.getString("Name");
this.path = par1NBTTagCompound.getString("Path");
this.burnTime = par1NBTTagCompound.getShort("BurnTime");
this.currentBurnTime = par1NBTTagCompound.getShort("CurrentBurnTime");
this.currentItemBurnTime = getItemBurnTime(this.recorderItemStacks[1]);
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
par1NBTTagCompound.setShort("BurnTime", (short)this.burnTime);
par1NBTTagCompound.setShort("CurrentBurnTime", (short)this.currentBurnTime);
par1NBTTagCompound.setString("Name", this.name);
par1NBTTagCompound.setString("Path", this.path);
NBTTagList var2 = new NBTTagList();
for (int var3 = 0; var3 < this.recorderItemStacks.length; ++var3)
{
if (this.recorderItemStacks[var3] != null)
{
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte)var3);
this.recorderItemStacks[var3].writeToNBT(var4);
var2.appendTag(var4);
}
}
par1NBTTagCompound.setTag("Items", var2);
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
public int getInventoryStackLimit()
{
return 64;
}
/**
* Returns an integer between 0 and the passed value representing how close the current item is to being completely
* cooked
*/
public int getCookProgressScaled(int par1)
{
return this.currentBurnTime * par1 / 200;
}
/**
* Returns an integer between 0 and the passed value representing how much burn time is left on the current fuel
* item, where 0 means that the item is exhausted and the passed value means that the item is fresh
*/
public int getBurnTimeRemainingScaled(int par1)
{
if (this.currentItemBurnTime == 0)
{
this.currentItemBurnTime = 200;
}
return this.burnTime * par1 / this.currentItemBurnTime;
}
/**
* Returns true if the recorder is currently burning
*/
public boolean isBurning()
{
return this.burnTime > 0;
}
/**
* Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
* ticks and creates a new spawn inside its implementation.
*/
public void updateEntity()
{
boolean var1 = this.burnTime > 0;
boolean var2 = false;
if (this.burnTime > 0)
{
--this.burnTime;
}
if (!this.worldObj.isRemote)
{
if (this.burnTime == 0 && this.canSmelt())
{
this.currentItemBurnTime = this.burnTime = getItemBurnTime(this.recorderItemStacks[1]);
if (this.burnTime > 0)
{
var2 = true;
if (this.recorderItemStacks[1] != null)
{
--this.recorderItemStacks[1].stackSize;
if (this.recorderItemStacks[1].stackSize == 0)
{
Item var3 = this.recorderItemStacks[1].getItem().getContainerItem();
this.recorderItemStacks[1] = var3 != null ? new ItemStack(var3) : null;
}
}
}
}
if (this.isBurning() && this.canSmelt())
{
++this.currentBurnTime;
if (this.currentBurnTime == 200)
{
this.currentBurnTime = 0;
this.smeltItem();
var2 = true;
}
}
else
{
this.currentBurnTime = 0;
}
}
if (var2)
{
this.onInventoryChanged();
}
}
/**
* Returns true if the recorder can smelt an item, i.e. has a source item, destination stack isn't full, etc.
*/
private boolean canSmelt()
{
if (this.recorderItemStacks[0] == null)
{
return false;
}
else
{
ItemStack var1 = RecorderRecipes.smelting().getSmeltingResult(this.recorderItemStacks[0].getItem().shiftedIndex);
return var1 == null ? false : (this.recorderItemStacks[2] == null ? true : (!this.recorderItemStacks[2].isItemEqual(var1) ? false : (this.recorderItemStacks[2].stackSize < this.getInventoryStackLimit() && this.recorderItemStacks[2].stackSize < this.recorderItemStacks[2].getMaxStackSize() ? true : this.recorderItemStacks[2].stackSize < var1.getMaxStackSize())));
}
}
/**
* Turn one item from the recorder source stack into the appropriate smelted item in the recorder result stack
*/
public void smeltItem()
{
if (this.canSmelt())
{
ItemStack var1 = RecorderRecipes.smelting().getSmeltingResult(this.recorderItemStacks[0].getItem().shiftedIndex);
if (this.recorderItemStacks[2] == null)
{
this.recorderItemStacks[2] = var1.copy();
}
else if (this.recorderItemStacks[2].itemID == var1.itemID)
{
++this.recorderItemStacks[2].stackSize;
}
--this.recorderItemStacks[0].stackSize;
if (this.recorderItemStacks[0].stackSize <= 0)
{
this.recorderItemStacks[0] = null;
}
System.out.println("<TileEntityRecorder>(smeltItem) Name: "+this.name);
System.out.println("<TileEntityRecorder>(smeltItem) Path: "+this.path);
ItemCustomRecord custom = (ItemCustomRecord)(var1.getItem());
custom.SetName(this.name);
custom.SetPath(this.path);
}
}
/**
* Returns the number of ticks that the supplied fuel item will keep the recorder burning, or 0 if the item isn't
* fuel
*/
public static int getItemBurnTime(ItemStack par0ItemStack)
{
return 250;
}
/**
* Return true if item is a fuel source (getItemBurnTime() > 0).
*/
public static boolean isItemFuel(ItemStack par0ItemStack)
{
return getItemBurnTime(par0ItemStack) > 0;
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
{
return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
}
public void openChest() {}
public void closeChest() {}
public void setDiscName(final String aName)
{
this.name = aName;
System.out.println("<TileEntityRecorder>Record Name Set! Name: " + this.name);
}
public void setMusicPath(final String aName)
{
this.path = aName;
System.out.println("<TileEntityRecorder>Record Path Set! Path: " + this.path);
}
}
ItemCustomRecord.java
package net.minecraft.src;
import java.util.List;
public class ItemCustomRecord extends Item
{
/** The name of the record. */
public volatile String recordName;
public volatile String musicName;
protected ItemCustomRecord(int par1)
{
super(par1);
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.tabMisc);
this.recordName= "Untitled";
this.musicName = "cat";
}
public void SetName(final String par1)
{
this.recordName = par1;
System.out.println("<ItemCustomRecord>Name Set! Name: "+this.recordName);
}
public void SetPath(final String par1)
{
this.musicName = par1;
System.out.println("<ItemCustomRecord>Path Set! Path: "+this.musicName);
}
/**
* Callback for item usage. If the item does something special on right clicking, he will have one of those. Return
* True if something happen and false if it don't. This is for ITEMS, not BLOCKS
*/
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (par3World.getBlockId(par4, par5, par6) == Block.jukebox.blockID && par3World.getBlockMetadata(par4, par5, par6) == 0)
{
if (par3World.isRemote)
{
return true;
}
else
{
((BlockJukeBox)Block.jukebox).insertRecord(par3World, par4, par5, par6, this.shiftedIndex);
par3World.playAuxSFXAtEntity((EntityPlayer)null, 1006, par4, par5, par6, this.shiftedIndex);
--par1ItemStack.stackSize;
return true;
}
}
else
{
return false;
}
}
/**
* allows items to add custom lines of information to the mouseover description
*/
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
par3List.add("Custom - " + this.recordName);
}
/**
* Return an item rarity from EnumRarity
*/
public EnumRarity getRarity(ItemStack par1ItemStack)
{
return EnumRarity.epic;
}
}
我希望你们能帮助我,因为这真的减慢了我的模组速度......好吧,它实际上戛然而止。非常感谢所有帮助!
最佳答案
字符串是不可变的对象,创建后就无法更改。
关于java - 为什么 java (minecraft) 似乎正在重置我的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13319224/
我有一个“设置首选项”屏幕。它有一个 ListPreference 和一个 CheckBoxPreference。当我选择 ListPreference 的一项时,我想更改应用程序的日期格式。另外,通
我试图找到创 build 置/配置窗口的示例。单击菜单项中的“选项”操作可启动设置窗口。我想弄清楚如何从主窗口打开第二个窗口。以及新窗口如何将设置信息返回主窗口。尝试使用 QDialog 或一些继承的
我在 Lnux 上有 Qt 应用程序。我想为此创建一个可执行文件/设置以便在 Windows 上分发它并且不需要安装 Qt。我通过包含所有 dll 为此创建了可执行文件但要运行它,用户需要进入文件夹。
我正在尝试创建一个有点动态的 html 类,它根据类末尾包含的数字设置宽度 %。注意:类名将始终以“gallery-item-”开头 示例:div.gallery-item-20 = 20% 宽度 我
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
在我的应用程序中,我想记住一些变量,例如,如果用户登录过一次,那么他们将在下次重新打开应用程序时登录,或者如果他们决定禁用某些提醒,应用程序可以检查该变量是否是错误的,将不再显示该提醒。理想情况下,这
我在 Netbeans 中开发了一个应用程序,它连接到远程计算机的消息队列并发送消息。该应用程序还有其他功能。项目完成后,我清理并构建应用程序,然后 Netbeans 创建一个 jar 文件。 但我的
我创建了一个 Outlook 加载项,需要创建一个设置以使其可分发(我是新手,所以请原谅新手评论) Outlook -2010 Vs -2010 .Net 4.0 我读了一些地方,最简单的方法就是发
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: How to make installer pack of Java swing Application Proje
这个问题肯定已经被很多人解决过很多次了,但是经过几个小时的研究,我仍然没有找到我要找的东西。 我有一个 ExportSettings.settings 文件,其中包含一堆设置( bool 值、字符串、
我想为我的项目创建一个安装程序,以便它可以安装在任何电脑上而无需安装头文件。我怎样才能做到这一点? 最佳答案 一般有两种分发程序的方法: 源代码分发(要构建的源代码)。最常见的方法是使用 GNU au
如何在这样的动态壁纸中创 build 置 Activity ? Example Picture 我只用一个简单的文本构建了设置 Activity ,但遇到了一些问题。第一个问题是我不能为此 Activ
我用 GUI 创建了一个简单的软件。它有几个源文件。我可以在我的编辑器中运行该项目。我认为它已经为 1.0 版本做好了准备。但我不知道如何为我的软件创 build 置/安装程序。 源代码是python
我的 SettingsActivity当前扩展了 Android Studio 生成的类,AppCompatPreferenceActivity扩展 PreferenceActivity . Acti
我正在使用 .NET 为 IE 开发工具栏。目前,我使用 gacutil 插入我的 .NET 程序集,并使用 regasm 注册我的 COM 程序集。 我想为项目创建一个设置 (MSI),但我似乎无法
在为设置页面创建 Activity 后,我注意到 if (mCurrentValue !== value) 中的 mCurrentValue !== value 返回警告: Identity equa
我在 Visual Studio 10 中创建了一个项目,该项目使用 Mysql 数据库和 Crystalreports 以及 它。但是我不知道如何进行自动安装 Mysql 和 Crystalrepo
我正在尝试在我的 C# 项目中使用 Sqlite 数据库,并且我在 IDE 中做得很好。我的问题是当我为我的项目制作安装包并安装它时,程序无法访问 sqlite 数据库。我也知道这是因为用户没有访问文
我有一个大型 Web 应用程序(带有 11 子系统的 ErP),我想使用 Microsoft WebPI 为它创建一个设置。 目前,我们每周向客户发送一次应用程序(用于每周更新)。 我们在此应用程序中
所以我对工资单申请的最终查询是 - 如何为薪资申请创 build 置? 我需要知道的一切- 如何将设置项目添加到我现有的解决方案 如何将解决方案中的文件添加到安装项目中,以及添加哪些文件添加和在什么文
我是一名优秀的程序员,十分优秀!